unit fGlsTree;
{ ComputeTreeRealCoords
  TreePolygonVertices: array of array of array of real;
  TreePolyImageVertices: array of array of array of Integer;
  TreePolygonVerticesNumber: array of integer;
  barfys
  B (Black Base Extents)    clBlack
  A  (Aqua  1st Stem)       clAqua
  R  (Red   2nd Stem )      clRed
  F  (Fuchsia 3rdStem)      clFuchsia  (Purple)
  T  (Yellow 4th Stem)      clYellow
  S  (Silver 5th Stem)      clSilver }

{ PruneShapeDisplayBtnClick }

(*
  GlsTreeFrm in 'GlsTreeFrm.pas' {aGlsTreeForm},
  GlsPluginMenuFrm in 'GlsPluginMenuFrm.pas' {GlsPluginMenuForm},
  GlsAboutFrm in 'GlsAboutFrm.pas' {GlsAboutForm},
  GlsProgressFormUnit in 'GlsProgressFormUnit.pas' {GlsProgressForm},
  GlsViewerFrm in 'GlsViewerFrm.pas' {GlsViewerForm},
  GlsOglAboutFrm in 'GlsOglAboutFrm.pas' {AboutForm},
  glstdemofrm in 'glstdemofrm.pas' {ATreeForm},
  GlsTreeUnit in 'GlsTreeUnit.pas';

  GlsPluginMenuFrm,
  GlsConstants,
  GlsTree,
  GlsModelParameters,
  GlsFrame, GlsONB, GlsMatrix, GlsVector,
  GlsTransformationList;
*)
interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.Imaging.Jpeg,
  Vcl.Imaging.pngimage,
  Winapi.ShellApi,
  Vcl.StdCtrls,
  Vcl.ExtCtrls,
  Vcl.ComCtrls,
  Vcl.Menus,
  Vcl.ExtDlgs,
  Vcl.Buttons,

  GLS.FileTGA,
  GLS.File3DS,

  fGlsPluginMenu,
  uConstants,
  uModelParameters,
  uGlsVector,
  uGlsTree;

type
  TDrawingTool = (dtEllipse, dtCSEllipse, dtPolygon, dtVTriangle, dtTriangle,
    dtTSTriangle, dtVPRectangle, dtVERectangle, dtVSRectangle, dtVDRectangle,
    dtVTRectangle, dtVFRectangle, dtVNRectangle, dtVMRectangle, dtVARectangle,
    dtVWRectangle, dtVCRectangle, dtVBRectangle, dtVRectangle, dtRectangle,
    dtRoundRect, dtLine, dtMLine, dtPBrush);

type
  TaGlsTreeForm = class(TForm)
    ScrollBox1: TScrollBox;
    TracerImage: TImage;
    Panel1: TPanel;
    PageControl1: TPageControl;
    Splitter1: TSplitter;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    TabSheet3: TTabSheet;
    TabSheet4: TTabSheet;
    TabSheet5: TTabSheet;
    TreeDefLabel: TLabel;
    TreeDefFileNameEdit: TEdit;
    OpenTreeDefFileBtn: TSpeedButton;
    SaveTreeDefFileBtn: TSpeedButton;
    ExitBtn: TSpeedButton;
    HelpBtn: TSpeedButton;
    GroupBox2: TGroupBox;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    ScaleFloatEdit: TEdit;
    ScaleVFloatEdit: TEdit;
    ZScaleFloatEdit: TEdit;
    ZScaleVFloatEdit: TEdit;
    GroupBox3: TGroupBox;
    Label7: TLabel;
    Label8: TLabel;
    RatioFloatEdit: TEdit;
    RatioPowerFloatEdit: TEdit;
    GroupBox4: TGroupBox;
    Label9: TLabel;
    Label10: TLabel;
    LobeDepthFloatEdit: TEdit;
    LobesNumberEdit: TEdit;
    pager: TPageControl;
    StemLevel0TabSheet: TTabSheet;
    ScalingParameters0GroupBox: TGroupBox;
    Label24: TLabel;
    Label25: TLabel;
    Label26: TLabel;
    Length0FloatEdit: TEdit;
    LengthV0FloatEdit: TEdit;
    Taper0FloatEdit: TEdit;
    CurvatureParameters0GroupBox: TGroupBox;
    Label31: TLabel;
    Label32: TLabel;
    Label33: TLabel;
    Label34: TLabel;
    Curve0FloatEdit: TEdit;
    CurveBack0FloatEdit: TEdit;
    CurveV0FloatEdit: TEdit;
    CurveRes0NumberEdit: TEdit;
    StemSplittingParameters0GroupBox: TGroupBox;
    Label28: TLabel;
    Label29: TLabel;
    Label30: TLabel;
    SplitAngle0FloatEdit: TEdit;
    SplitAngleV0FloatEdit: TEdit;
    SegSplits0FloatEdit: TEdit;
    Level1TS: TTabSheet;
    Level2TS: TTabSheet;
    LeafColorDialog: TColorDialog;
    OpenShapeDialog: TOpenDialog;
    SaveShapeDialog: TSaveDialog;
    Level3TS: TTabSheet;
    Level4TS: TTabSheet;
    WindStrengthTB: TTrackBar;
    Label37: TLabel;
    WindFromTB: TTrackBar;
    SunHeightTB: TTrackBar;
    SunFromTB: TTrackBar;
    Label43: TLabel;
    Label44: TLabel;
    Label45: TLabel;
    OpenPictureDialog1: TOpenPictureDialog;
    GroupBox5: TGroupBox;
    Label51: TLabel;
    Label52: TLabel;
    Label53: TLabel;
    SplitAngle1FloatEdit: TEdit;
    SplitAngleV1FloatEdit: TEdit;
    SegSplits1FloatEdit: TEdit;
    GroupBox6: TGroupBox;
    Label49: TLabel;
    Label50: TLabel;
    Label54: TLabel;
    Length1FloatEdit: TEdit;
    LengthV1FloatEdit: TEdit;
    Taper1FloatEdit: TEdit;
    GroupBox7: TGroupBox;
    Label55: TLabel;
    Vertices1NumberEdit: TEdit;
    GroupBox8: TGroupBox;
    Label47: TLabel;
    Label48: TLabel;
    Label56: TLabel;
    Label57: TLabel;
    Curve1FloatEdit: TEdit;
    CurveBack1FloatEdit: TEdit;
    CurveV1FloatEdit: TEdit;
    CurveRes1NumberEdit: TEdit;
    Label58: TLabel;
    Branches1NumberEdit: TEdit;
    GroupBox9: TGroupBox;
    Rotate1FloatEdit: TEdit;
    DownAngleV1FloatEdit: TEdit;
    RotateV1FloatEdit: TEdit;
    DownAngle1FloatEdit: TEdit;
    Label59: TLabel;
    Label60: TLabel;
    Label61: TLabel;
    Label62: TLabel;
    PrintTreeDefFileBtn: TSpeedButton;
    StatusBar: TStatusBar;
    GroupBox10: TGroupBox;
    Label64: TLabel;
    Label65: TLabel;
    Label66: TLabel;
    Length2FloatEdit: TEdit;
    LengthV2FloatEdit: TEdit;
    Taper2FloatEdit: TEdit;
    GroupBox11: TGroupBox;
    Label67: TLabel;
    Label68: TLabel;
    Label69: TLabel;
    SplitAngle2FloatEdit: TEdit;
    SplitAngleV2FloatEdit: TEdit;
    SegSplits2FloatEdit: TEdit;
    GroupBox12: TGroupBox;
    Label70: TLabel;
    Label71: TLabel;
    Vertices2NumberEdit: TEdit;
    Branches2NumberEdit: TEdit;
    GroupBox13: TGroupBox;
    Label72: TLabel;
    Label73: TLabel;
    Label74: TLabel;
    Label75: TLabel;
    Rotate2FloatEdit: TEdit;
    DownAngleV2FloatEdit: TEdit;
    RotateV2FloatEdit: TEdit;
    DownAngle2FloatEdit: TEdit;
    GroupBox14: TGroupBox;
    Label76: TLabel;
    Label77: TLabel;
    Label78: TLabel;
    Label79: TLabel;
    Curve2FloatEdit: TEdit;
    CurveBack2FloatEdit: TEdit;
    CurveV2FloatEdit: TEdit;
    CurveRes2NumberEdit: TEdit;
    GroupBox15: TGroupBox;
    Label80: TLabel;
    Label81: TLabel;
    Label82: TLabel;
    Length3FloatEdit: TEdit;
    LengthV3FloatEdit: TEdit;
    Taper3FloatEdit: TEdit;
    GroupBox16: TGroupBox;
    Label83: TLabel;
    Label84: TLabel;
    Label85: TLabel;
    SplitAngle3FloatEdit: TEdit;
    SplitAngleV3FloatEdit: TEdit;
    SegSplits3FloatEdit: TEdit;
    GroupBox17: TGroupBox;
    Label86: TLabel;
    Label87: TLabel;
    Vertices3NumberEdit: TEdit;
    Branches3NumberEdit: TEdit;
    GroupBox18: TGroupBox;
    Label88: TLabel;
    Label89: TLabel;
    Label90: TLabel;
    Label91: TLabel;
    Rotate3FloatEdit: TEdit;
    DownAngleV3FloatEdit: TEdit;
    RotateV3FloatEdit: TEdit;
    DownAngle3FloatEdit: TEdit;
    GroupBox19: TGroupBox;
    Label92: TLabel;
    Label93: TLabel;
    Label94: TLabel;
    Label95: TLabel;
    Curve3FloatEdit: TEdit;
    CurveBack3FloatEdit: TEdit;
    CurveV3FloatEdit: TEdit;
    CurveRes3NumberEdit: TEdit;
    GroupBox20: TGroupBox;
    Label96: TLabel;
    Label97: TLabel;
    Label98: TLabel;
    Length4FloatEdit: TEdit;
    LengthV4FloatEdit: TEdit;
    Taper4FloatEdit: TEdit;
    GroupBox21: TGroupBox;
    Label99: TLabel;
    Label100: TLabel;
    Label101: TLabel;
    SplitAngle4FloatEdit: TEdit;
    SplitAngleV4FloatEdit: TEdit;
    SegSplits4FloatEdit: TEdit;
    GroupBox22: TGroupBox;
    Label102: TLabel;
    Label103: TLabel;
    Vertices4NumberEdit: TEdit;
    Branches4NumberEdit: TEdit;
    GroupBox23: TGroupBox;
    Label104: TLabel;
    Label105: TLabel;
    Label106: TLabel;
    Label107: TLabel;
    Rotate4FloatEdit: TEdit;
    DownAngleV4FloatEdit: TEdit;
    RotateV4FloatEdit: TEdit;
    DownAngle4FloatEdit: TEdit;
    GroupBox24: TGroupBox;
    Label108: TLabel;
    Label109: TLabel;
    Label110: TLabel;
    Label111: TLabel;
    Curve4FloatEdit: TEdit;
    CurveBack4FloatEdit: TEdit;
    CurveV4FloatEdit: TEdit;
    CurveRes4NumberEdit: TEdit;
    Level5TS: TTabSheet;
    GroupBox25: TGroupBox;
    Label112: TLabel;
    Label113: TLabel;
    Label114: TLabel;
    Length5FloatEdit: TEdit;
    LengthV5FloatEdit: TEdit;
    Taper5FloatEdit: TEdit;
    GroupBox26: TGroupBox;
    Label115: TLabel;
    Label116: TLabel;
    Label117: TLabel;
    SplitAngle5FloatEdit: TEdit;
    SplitAngleV5FloatEdit: TEdit;
    SegSplits5FloatEdit: TEdit;
    GroupBox27: TGroupBox;
    Label118: TLabel;
    Label119: TLabel;
    Vertices5NumberEdit: TEdit;
    Branches5NumberEdit: TEdit;
    GroupBox28: TGroupBox;
    Label120: TLabel;
    Label121: TLabel;
    Label122: TLabel;
    Label123: TLabel;
    Rotate5FloatEdit: TEdit;
    DownAngleV5FloatEdit: TEdit;
    RotateV5FloatEdit: TEdit;
    DownAngle5FloatEdit: TEdit;
    GroupBox29: TGroupBox;
    Label124: TLabel;
    Label125: TLabel;
    Label126: TLabel;
    Label127: TLabel;
    Curve5FloatEdit: TEdit;
    CurveBack5FloatEdit: TEdit;
    CurveV5FloatEdit: TEdit;
    CurveRes5NumberEdit: TEdit;
    GroupBox30: TGroupBox;
    LeafColorVariationCheckBox: TCheckBox;
    PickLeafColorBtn: TSpeedButton;
    LeafColorShape: TShape;
    Label41: TLabel;
    Label35: TLabel;
    LeafQualityFloatEdit: TEdit;
    AttractionUpFloatEdit: TEdit;
    Label16: TLabel;
    Label15: TLabel;
    LeafScaleXFloatEdit: TEdit;
    LeafScaleFloatEdit: TEdit;
    Label14: TLabel;
    Label13: TLabel;
    LeafShapeComboBox: TComboBox;
    LeavesNumberEdit: TEdit;
    Label12: TLabel;
    Label131: TLabel;
    Label132: TLabel;
    DistanceTrackBar: TTrackBar;
    Label133: TLabel;
    WindGustTB: TTrackBar;
    Label136: TLabel;
    Label137: TLabel;
    SunStrengthTB: TTrackBar;
    PruneImage: TImage;
    PruneShapeDisplayBtn: TSpeedButton;
    LeafTextureBtn: TSpeedButton;
    LeafTextureEdit: TEdit;
    Label128: TLabel;
    LeafShapeEdit: TEdit;
    LeafShapeBtn: TSpeedButton;
    Label130: TLabel;
    Label139: TLabel;
    GroupBox31: TGroupBox;
    FruitImageBtn: TSpeedButton;
    Label140: TLabel;
    FruitImageEdit: TEdit;
    Label135: TLabel;
    FruitShapeFileBtn: TSpeedButton;
    FruitShapeFileEdit: TEdit;
    Label129: TLabel;
    FruitTextureBtn: TSpeedButton;
    FruitTextureEdit: TEdit;
    LeafImageBtn: TSpeedButton;
    LeafImageEdit: TEdit;
    LeafShapeSaverBtn: TSpeedButton;
    FruitShapeSaverBtn: TSpeedButton;
    SaveTdfDialog: TSaveDialog;
    OpenTdfDialog: TOpenDialog;
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Render1: TMenuItem;
    Help1: TMenuItem;
    Contents1: TMenuItem;
    OnHelp1: TMenuItem;
    Me1: TMenuItem;
    About1: TMenuItem;
    SelectPluginModules: TMenuItem;
    Tree1: TMenuItem;
    Load1: TMenuItem;
    Save1: TMenuItem;
    Leaf1: TMenuItem;
    Fruit1: TMenuItem;
    N1: TMenuItem;
    Exit1: TMenuItem;
    Print1: TMenuItem;
    Trace1: TMenuItem;
    N2: TMenuItem;
    ImageLoad1: TMenuItem;
    N3: TMenuItem;
    ShapeLoad1: TMenuItem;
    ShapeSave1: TMenuItem;
    N4: TMenuItem;
    BarkLoad1: TMenuItem;
    DistanceLabel: TLabel;
    WindStrengthLabel: TLabel;
    WindFromLabel: TLabel;
    WindGustLabel: TLabel;
    SunStrengthLabel: TLabel;
    SunHeightLabel: TLabel;
    SunFromLabel: TLabel;
    Label151: TLabel;
    FruitColorShape: TShape;
    PickFruitColorBtn: TSpeedButton;
    FruitColorVariationCheckBox: TCheckBox;
    Image2: TMenuItem;
    ShapeLoad2: TMenuItem;
    ShapeSave2: TMenuItem;
    TextureLoad1: TMenuItem;
    Image3: TMenuItem;
    ShapeLoad3: TMenuItem;
    ShapeSave3: TMenuItem;
    TextureLoad2: TMenuItem;
    FruitPercentEdit: TEdit;
    FruitLocationRG: TRadioGroup;
    FruitPerEdit: TEdit;
    Label143: TLabel;
    Label144: TLabel;
    LeafLocationRG: TRadioGroup;
    Label145: TLabel;
    LeafsPerEdit: TEdit;
    LeafGroupingCB: TComboBox;
    DefinitionSaveAs1: TMenuItem;
    ShapeSaveAs1: TMenuItem;
    ShapeSaveAs2: TMenuItem;
    GLSViewer1: TMenuItem;
    TabSheet6: TTabSheet;
    RichEdit1: TRichEdit;
    Label146: TLabel;
    ManOpenLeafShapeFileBtn: TSpeedButton;
    ManSaveLeafShapeFileBtn: TSpeedButton;
    Label147: TLabel;
    ManOpenFruitShapeFileBtn: TSpeedButton;
    ManSaveFruitShapeFileBtn: TSpeedButton;
    ManualShapeInputFilenameEdit: TEdit;
    Label148: TLabel;
    Label149: TLabel;
    TreeInputname1: TMenuItem;
    BaseExtents: TMenuItem;
    FirstLimbLevel: TMenuItem;
    SecondLimbLevel: TMenuItem;
    ThirdLimbLevel: TMenuItem;
    FourthLimbLevel: TMenuItem;
    ManDisplayLeafBtn: TSpeedButton;
    CClear1: TMenuItem;
    DDraw1: TMenuItem;
    ADrawAll1: TMenuItem;
    TreeParameter1: TMenuItem;
    TraceInput1: TMenuItem;
    TICNone: TMenuItem;
    PrinterSetupDialog: TPrinterSetupDialog;
    SetupPrinterBtn: TSpeedButton;
    Label152: TLabel;
    FTracerFinished1: TMenuItem;
    N5: TMenuItem;
    SaveImage1: TMenuItem;
    SaveScreenImageDialog: TSaveDialog;
    ManDisplayFruitBtn: TSpeedButton;
    ShapeSaveAs: TMenuItem;
    SaveAnnoDefinitionBtn: TSpeedButton;
    FifthLimbLevel: TMenuItem;
    TreeTest1: TMenuItem;
    Label154: TLabel;
    Label155: TLabel;
    Label156: TLabel;
    Label157: TLabel;
    Label158: TLabel;
    Label159: TLabel;
    DisplayTreeBtn: TSpeedButton;
    Label160: TLabel;
    LeafBackColorVariationCheckBox: TCheckBox;
    LeafBackColorShape: TShape;
    PickLeafBackColorBtn: TSpeedButton;
    LSystem1: TMenuItem;
    N6: TMenuItem;
    Mathings1: TMenuItem;
    HighLevelTracing1: TMenuItem;
    Leaf2: TMenuItem;
    Stem1: TMenuItem;
    General1: TMenuItem;
    Overview1: TMenuItem;
    Menu1: TMenuItem;
    N7: TMenuItem;
    Prune1: TMenuItem;
    Level6TS: TTabSheet;
    GroupBox33: TGroupBox;
    Label142: TLabel;
    Label162: TLabel;
    Label163: TLabel;
    Length6FloatEdit: TEdit;
    LengthV6FloatEdit: TEdit;
    Taper6FloatEdit: TEdit;
    GroupBox34: TGroupBox;
    Label164: TLabel;
    Label165: TLabel;
    Label166: TLabel;
    SplitAngle6FloatEdit: TEdit;
    SplitAngleV6FloatEdit: TEdit;
    SegSplits6FloatEdit: TEdit;
    Label167: TLabel;
    GroupBox35: TGroupBox;
    Label168: TLabel;
    Label169: TLabel;
    Vertices6NumberEdit: TEdit;
    Branches6NumberEdit: TEdit;
    GroupBox36: TGroupBox;
    Label170: TLabel;
    Label171: TLabel;
    Label172: TLabel;
    Label173: TLabel;
    Rotate6FloatEdit: TEdit;
    DownAngleV6FloatEdit: TEdit;
    RotateV6FloatEdit: TEdit;
    DownAngle6FloatEdit: TEdit;
    GroupBox37: TGroupBox;
    Label174: TLabel;
    Label175: TLabel;
    Label176: TLabel;
    Label177: TLabel;
    Curve6FloatEdit: TEdit;
    CurveBack6FloatEdit: TEdit;
    CurveV6FloatEdit: TEdit;
    CurveRes6NumberEdit: TEdit;
    FruitTypeRG: TComboBox;
    Label179: TLabel;
    FruitScaleFloatEdit: TEdit;
    Label180: TLabel;
    FruitScaleXFloatEdit: TEdit;
    Label181: TLabel;
    GroupBox1: TGroupBox;
    ShapeLabel: TLabel;
    Label6: TLabel;
    Label178: TLabel;
    ShapeComboBox: TComboBox;
    LevelsNumberEdit: TEdit;
    SeasonComboBox: TComboBox;
    Label36: TLabel;
    Label42: TLabel;
    RandomTreeSeedNumberEdit: TEdit;
    Label38: TLabel;
    Label39: TLabel;
    HealthTrackBar: TTrackBar;
    HealthLabel: TLabel;
    Label40: TLabel;
    Label46: TLabel;
    LoadTreeImageBtn: TSpeedButton;
    Label134: TLabel;
    LoadTreeShapeBtn: TSpeedButton;
    SaveTreeShapeBtn: TSpeedButton;
    TreeImageEdit: TEdit;
    TreeShapeEdit: TEdit;
    GroupBox32: TGroupBox;
    TreeShapeRG: TRadioGroup;
    TICRG: TRadioGroup;
    GroupBox39: TGroupBox;
    Label21: TLabel;
    Label20: TLabel;
    Label19: TLabel;
    Label18: TLabel;
    Label17: TLabel;
    PrunePowerHighFloatEdit: TEdit;
    PrunePowerLowFloatEdit: TEdit;
    PruneWidthPeakFloatEdit: TEdit;
    PruneWidthFloatEdit: TEdit;
    PruneRatioFloatEdit: TEdit;
    GroupBox40: TGroupBox;
    Label141: TLabel;
    LoadTreeBarkBtn: TSpeedButton;
    TreeBarkEdit: TEdit;
    Label153: TLabel;
    PickTreeColorBtn: TSpeedButton;
    TreeColorShape: TShape;
    TreeColorVariationCheckBox: TCheckBox;
    Label22: TLabel;
    Scale0FloatEdit: TEdit;
    Label23: TLabel;
    ScaleV0FloatEdit: TEdit;
    GroupBox38: TGroupBox;
    Label27: TLabel;
    Label1: TLabel;
    Label63: TLabel;
    BaseSplits0NumberEdit: TEdit;
    BaseSizeFloatEdit: TEdit;
    FlareFloatEdit: TEdit;
    GroupBox41: TGroupBox;
    Vertices0Label: TLabel;
    Vertices0NumberEdit: TEdit;
    Label138: TLabel;
    Leaves1NumberEdit: TEdit;
    Label11: TLabel;
    Label150: TLabel;
    Leaves0NumberEdit: TEdit;
    Label161: TLabel;
    Leaves2NumberEdit: TEdit;
    Label182: TLabel;
    Leaves3NumberEdit: TEdit;
    Label183: TLabel;
    Leaves4NumberEdit: TEdit;
    Label184: TLabel;
    Leaves5NumberEdit: TEdit;
    Label185: TLabel;
    Leaves6NumberEdit: TEdit;
    WindActiveCB: TCheckBox;

    procedure FormCreate(Sender: TObject);
    procedure DisplayHint(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ExitBtnClick(Sender: TObject);

    procedure SaveImage1Click(Sender: TObject);

    procedure Contents1Click(Sender: TObject);
    procedure OnHelp1Click(Sender: TObject);
    procedure About1Click(Sender: TObject);

    procedure SelectPluginModulesClick(Sender: TObject);
    { procedure ModelInputComponentChange(Sender: TObject); }
    procedure RandomTreeSeedNumberEditChange(Sender: TObject);
    procedure GLSViewer1Click(Sender: TObject);
    procedure LevelsNumberEditExit(Sender: TObject);

    procedure PrintTreeDefFileBtnClick(Sender: TObject);
    procedure SaveAnnoDefinitionBtnClick(Sender: TObject);
    procedure SaveOrPrint(Switch: Integer);

    procedure SaveTreeDefFileBtnClick(Sender: TObject);
    procedure OpenTreeDefFileBtnClick(Sender: TObject);
    procedure LoadTreeImageBtnClick(Sender: TObject);
    procedure LoadTreeShapeBtnClick(Sender: TObject);
    procedure SaveTreeShapeBtnClick(Sender: TObject);
    procedure SaveTreeShape(Filename: String);
    procedure LoadTreeBarkBtnClick(Sender: TObject);

    procedure LeafImageBtnClick(Sender: TObject);
    procedure LeafShapeBtnClick(Sender: TObject);
    procedure LeafShapeSaverBtnClick(Sender: TObject);
    Function LeafShapeChecker(LeafShape: Integer): Boolean;

    procedure LoadLeafShape(Filename: string; InShape: Integer);
    procedure SaveLeafShape(Filename: string);
    procedure LeafTextureBtnClick(Sender: TObject);
    procedure PickLeafColorBtnClick(Sender: TObject);

    procedure ManOpenLeafShapeFileBtnClick(Sender: TObject);
    procedure ManSaveLeafShapeFileBtnClick(Sender: TObject);
    procedure ManOpenFruitShapeFileBtnClick(Sender: TObject);
    procedure ManSaveFruitShapeFileBtnClick(Sender: TObject);
    procedure ManDisplayLeafBtnClick(Sender: TObject);
    procedure ManDisplayFruitBtnClick(Sender: TObject);
    procedure BlankCanvas;

    procedure FruitImageBtnClick(Sender: TObject);
    procedure FruitTextureBtnClick(Sender: TObject);
    procedure FruitShapeFileBtnClick(Sender: TObject);
    procedure FruitShapeSaverBtnClick(Sender: TObject);
    procedure LoadFruitShape(Filename: string);
    procedure SaveFruitShape(Filename: string);

    procedure CClear1Click(Sender: TObject);
    procedure TraceInput1Click(Sender: TObject);
    procedure FTracerFinished1Click(Sender: TObject);
    procedure DDraw1Click(Sender: TObject);
    procedure ADrawAll1Click(Sender: TObject);
    procedure TICRGClick(Sender: TObject);

    procedure TICNoneClick(Sender: TObject);
    procedure SetupPrinterBtnClick(Sender: TObject);

    procedure BaseExtentsClick(Sender: TObject);
    procedure FirstLimbLevelClick(Sender: TObject);
    procedure SecondLimbLevelClick(Sender: TObject);
    procedure ThirdLimbLevelClick(Sender: TObject);
    procedure FourthLimbLevelClick(Sender: TObject);
    procedure TreeShapeRGClick(Sender: TObject);

    procedure TracerImageMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure TracerImageMouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Integer);
    procedure TracerImageMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);

    procedure ComputeTreeRealCoords;
    procedure ComputeLeafImageCoords;
    procedure ComputeLeafRealCoords;
    procedure ComputeFruitImageCoords(InX, InY: Integer);
    procedure ComputeFruitRealCoords;

    procedure PruneShapeDisplayBtnClick(Sender: TObject);

    procedure HealthTrackBarChange(Sender: TObject);
    procedure DistanceTrackBarChange(Sender: TObject);
    procedure WindStrengthTBChange(Sender: TObject);
    procedure WindGustTBChange(Sender: TObject);
    procedure WindFromTBChange(Sender: TObject);
    procedure SunHeightTBChange(Sender: TObject);
    procedure SunStrengthTBChange(Sender: TObject);
    procedure SunFromTBChange(Sender: TObject);
    procedure FifthLimbLevelClick(Sender: TObject);
    procedure TreeTest1Click(Sender: TObject);
    procedure PickTreeColorBtnClick(Sender: TObject);
    procedure PickFruitColorBtnClick(Sender: TObject);
    procedure DisplayTreeBtnClick(Sender: TObject);
    procedure PickLeafBackColorBtnClick(Sender: TObject);
    procedure LeafShapeComboBoxChange(Sender: TObject);
    procedure LSystem1Click(Sender: TObject);
    procedure Mathings1Click(Sender: TObject);
    procedure Leaf2Click(Sender: TObject);

  private

    DrawingToolPBrushWidth: Integer;
    TreeImageLoaded, LeafImageLoaded, FruitImageLoaded, ImageLoaded,
      FruityLeafStarted, Drawing: Boolean;
    DIYX3Y3, DIYX4Y4, Origin, MovePt: TPoint;
    { FruitList, LeafList, TreeList:TList; }
    DrawingTool: TDrawingTool;
    Function LoadImage(var InName: String): Boolean;
    procedure DrawShape(TopLeft, BottomRight, Tri, Quad: TPoint;
      AMode: TPenMode);
    procedure DrawTracedShape(Which: Integer);
  public

    GrabberImageBitmap: TBitmap;
    procedure InitModelParameters(ModelParameters: TModelParameters);
    { Pre: True
      Post: All model parameters inputted by the user have been assigned to
      the corresponding properties of the class FModelParameters. }
    procedure SaveTreeDefinition(Filename: string);
    { Pre: True
      Post: The current model parameters have been saved to FileName. }
    procedure LoadTreeDefinition(Filename: string);
    { Pre: FileName should point to an existing file.
      Post: The current model parameters have been set to the model parameters
      loaded from the tree definition file FileName. }
  end;

var
  aGlsTreeForm: TaGlsTreeForm;

implementation

uses
  fAbout,
  fGlsViewer,
  fGlsTreedemo,
  fGlsLSystem;

{$R *.DFM}

procedure TaGlsTreeForm.FormCreate(Sender: TObject);
var
  InString: String;
  f: TextFile;
begin
  // LeavesGrownTotal:=0;
  { GlsViewerCancelled:=True;
    GlsDemoCancelled:=True;
    GlsUserCancelled:=True;
    DisplayWithLeaves:=False;
    DemoTreePlanted:=False;
    TreePlanted:=False; }
  AnimationActive := False;
  DistanceActive := False;
  WindAnimationActive := False;
  { Anime360Counter:=0;
    WindSign:=0;
    TreeAddedLeavesTotal:=0;
    Bolebusted:=0; }

  RandomTreeSeedNumber := 0;
  RandomTreeSeedNumberEdit.Text := '0';
  HealthTrackBar.Position := 100;
  SeasonComboBox.ItemIndex := 2; // Summer
  FruitTypeRG.ItemIndex := 0;
  LeafGroupingCB.ItemIndex := 0;
  GlobalLevelsNumber := 1; // CANNOT be <1
  LevelsNumberEdit.Text := Inttostr(GlobalLevelsNumber);
  Drawing := False;
  FruityLeafStarted := False;
  TreeImageLoaded := False;
  LeafImageLoaded := False;
  FruitImageLoaded := False;
  FruitPolygonVerticesNumber := -1;
  DisplayWithLeaves := True;
  ImageLoaded := False;
  GrabberImageBitmap := TBitmap.Create;
  DrawingTool := dtRectangle;
  DrawingToolPBrushWidth := 3;
  TracerImage.Canvas.Brush.Color := clWhite;
  TracerImage.Canvas.FillRect(Rect(0, 0, 256, 256));
  TracerImage.Canvas.Brush.Style := bsClear;
  GlsImagePath := ExtractFilePath(ParamStr(0));
  GlsDefinitionPath := GlsImagePath;
  GlsTexturePath := GlsImagePath;
  GlsShapePath := GlsImagePath;
  LeafShapeEdit.Text := ExtractFilePath(ParamStr(0)) + 'tree data\' +
    'gum-black_leaf_oval.lsf';
  GlsShapePath := ExtractFilePath(LeafShapeEdit.Text);
  LoadLeafShape(LeafShapeEdit.Text, 0);
  LeafTextureEdit.Text := ExtractFilePath(ParamStr(0)) + 'tree data\' +
    'gum-black_leaf_oval.jpg';

  // Update the main form caption
  aGlsTreeForm.Caption := 'GLS TReal v' + TREAL_VERSION;

  { Use the english decimal and thousands seperator characters }
  FormatSettings.DecimalSeparator := '.';
  FormatSettings.ThousandSeparator := ',';
  DoubleBuffered := True;

  // Load info from GlsTreal.ini
  if FileExists(ExtractFilePath(ParamStr(0)) + 'glstreal.ini') then
  begin // Read the settings from the Treal.ini
    try
      AssignFile(f, ExtractFilePath(ParamStr(0)) + 'glstreal.ini');
      try
        Reset(f);
        Readln(f, InString);
        TreeDefFileNameEdit.Text := InString;
        GlsDefinitionPath := ExtractFilePath(TreeDefFileNameEdit.Text);
        Readln(f, GlsImagePath);
        Readln(f, GlsTexturePath);
        Readln(f, GlsShapePath);
        Readln(f, InString);
        HealthTrackBar.Position := StrtoInt(InString); // 100;
        Readln(f, InString);
        SeasonComboBox.ItemIndex := StrtoInt(InString); // 2;
        Readln(f, InString);
        RandomTreeSeedNumberEdit.Text := InString; // '0';
        RandomTreeSeedNumber := StrtoInt(RandomTreeSeedNumberEdit.Text);
      except
        on EInOutError do
        begin
          MessageDlg('glstreal.ini corrupt!', mtError, [mbOK], 0);
        end;
      end;
    finally
      CloseFile(f);
    end;
  end
  else
  begin
    try
      AssignFile(f, ExtractFilePath(ParamStr(0)) + 'glstreal.ini');
      try
        Rewrite(f);
        InString := TreeDefFileNameEdit.Text;
        Writeln(f, InString);
        Writeln(f, GlsImagePath);
        Writeln(f, GlsTexturePath);
        Writeln(f, GlsShapePath);
        InString := Inttostr(HealthTrackBar.Position);
        Writeln(f, InString);
        InString := Inttostr(SeasonComboBox.ItemIndex);
        Writeln(f, InString);
        InString := RandomTreeSeedNumberEdit.Text;
        Writeln(f, InString);
      except
        on EInOutError do
        begin
          MessageDlg('glstreal.ini corrupted!', mtError, [mbOK], 0);
        end;
      end;
    finally
      CloseFile(f);
    end;
  end;
  { HealthTrackBar.Position
    SeasonComboBox.ItemIndex
    RandomSeedNumberEdit.SetValue(
    TreeDefinitionFileName }
  if FileExists(TreeDefFileNameEdit.Text) then
    LoadTreeDefinition(TreeDefFileNameEdit.Text);
  // Load tree definition file if one was specified using the command line
  if ParamCount > 0 then
    if FileExists(ParamStr(1)) then
      LoadTreeDefinition(ParamStr(1));
end;

procedure TaGlsTreeForm.DisplayHint(Sender: TObject);
begin
  StatusBar.Panels[0].Text := Application.Hint;
end;

procedure TaGlsTreeForm.FormActivate(Sender: TObject);
begin
  Application.OnHint := DisplayHint; // App
end;

procedure TaGlsTreeForm.FormClose(Sender: TObject; var Action: TCloseAction);
var
  InString: String;
  f: TextFile;
begin
  // Save info as GlsTreal.ini
  try
    AssignFile(f, ExtractFilePath(ParamStr(0)) + 'glstreal.ini');
    try
      Rewrite(f);
      InString := TreeDefFileNameEdit.Text;
      Writeln(f, InString);
      Writeln(f, GlsImagePath);
      Writeln(f, GlsTexturePath);
      Writeln(f, GlsShapePath);
      InString := Inttostr(HealthTrackBar.Position);
      Writeln(f, InString);
      InString := Inttostr(SeasonComboBox.ItemIndex);
      Writeln(f, InString);
      InString := RandomTreeSeedNumberEdit.Text;
      Writeln(f, InString);
    except
      on EInOutError do
      begin
        MessageDlg('glstreal.ini corrupt!', mtError, [mbOK], 0);
      end;
    end;
  finally
    CloseFile(f);
  end;
  GrabberImageBitmap.Free;
end;

procedure TaGlsTreeForm.ExitBtnClick(Sender: TObject);
begin
  Close;
end;

procedure TaGlsTreeForm.SaveImage1Click(Sender: TObject);
begin // SaveImageDialog
  SaveScreenImageDialog.Initialdir := GlsImagePath;
  SaveScreenImageDialog.Filename :=
    ChangeFileExt(TreeDefFileNameEdit.Text, '.bmp');
  if SaveScreenImageDialog.Execute then
  begin
    Application.ProcessMessages;
    TracerImage.Picture.Savetofile(SaveScreenImageDialog.Filename);
    GlsImagePath := ExtractFilePath(SaveScreenImageDialog.Filename);
  end;
end;

// -----------------------------------------------------
// -----------------------------------------------------
procedure TaGlsTreeForm.Contents1Click(Sender: TObject);
begin
  ShellExecute(Application.Handle, // handle to parent window
    'open', // pointer to string that specifies operation to perform
    PChar(ExtractFilePath(ParamStr(0)) + 'help\glstreal.htm'),
    { PChar(POVRayExecutable), }// pointer to filename or folder name string
    '' { PChar(POVRayCommandLine) } ,
    // pointer to string that specifies executable-file parameters
    PChar(ExtractFilePath(ParamStr(0)) + 'help'),
    // pointer to string that specifies default directory
    SW_SHOWNORMAL);
end;

procedure TaGlsTreeForm.OnHelp1Click(Sender: TObject);
begin // MS Help
  Application.HelpCommand(HELP_HELPONHELP, 0);
end;

{ Help }
procedure TaGlsTreeForm.Leaf2Click(Sender: TObject);
var
  s: String;
  Item: TMenuItem;
begin
  s := ExtractFilePath(ParamStr(0)) + 'help\';
  Item := Sender as TMenuItem;
  Case Item.tag of
    2:
      s := s + 'glstree_menu.htm'; { glstree_menu.htm }
    3:
      s := s + 'glstree_trace.htm'; { glstree_trace.htm HighLevelTracing1 }
    4:
      s := s + 'glstree_general.htm'; { glstree_general.htm  General1 }
    5:
      s := s + 'glstree_stem.htm'; { glstree_stem.htm  Stem1 }
    6:
      s := s + 'glstree_leaf.htm'; { glstree_leaf.htm  Leaf2 }
    7:
      s := s + 'glstree_prune.htm'; { glstree_prune.htm }
  else
    s := s + 'glstreehelp.htm'; { 1 Overview.. catch all too }
  end;
  ShellExecute(Application.Handle, // handle to parent window
    'open', // pointer to string that specifies operation to perform
    PChar(s), { PChar(POVRayExecutable), }
    // pointer to filename or folder name string
    '' { PChar(POVRayCommandLine) } ,
    // pointer to string that specifies executable-file parameters
    PChar(ExtractFilePath(ParamStr(0)) + 'help'),
    // pointer to string that specifies default directory
    SW_SHOWNORMAL);
end;

procedure TaGlsTreeForm.About1Click(Sender: TObject);
begin
  FormAbout := TFormAbout.Create(Application);
  try
    FormAbout.ShowModal;
  finally
    FormAbout.Release;
  end;
end;
// -----------------------------------------------------
// -----------------------------------------------------

procedure TaGlsTreeForm.SelectPluginModulesClick(Sender: TObject);
begin
  GlsPluginMenuForm.ShowModal;
end;

procedure TaGlsTreeForm.GLSViewer1Click(Sender: TObject);
begin
  WindAnimationActive := WindActiveCB.Checked;
  FormGlsViewer.WindAnimationCB.Checked := WindAnimationActive;
  DisplayWithLeaves := True;
  FormGlsViewer.show;
  FormGlsViewer.LoadParameters;
end;

procedure TaGlsTreeForm.DisplayTreeBtnClick(Sender: TObject);
begin
  DisplayWithLeaves := False;
  FormGlsViewer.show;
  FormGlsViewer.LoadParameters;
end;

procedure TaGlsTreeForm.TreeTest1Click(Sender: TObject);
begin
  ATreeForm := TATreeForm.Create(Application);
  try
    ATreeForm.ShowModal;
  finally
    ATreeForm.Release;
  end;
end;

procedure TaGlsTreeForm.LSystem1Click(Sender: TObject);
begin
  LSystemForm := TLSystemForm.Create(Application);
  try
    LSystemForm.ShowModal;
  finally
    LSystemForm.Release;
  end;
end;

procedure TaGlsTreeForm.Mathings1Click(Sender: TObject);
begin
  { }
end;

// -----------------------------------------------------
(*
  procedure TaGlsTreeForm.ModelInputComponentChange(Sender: TObject);
  begin
  { The check for nil here is required, since all values assigned to the
  input components via the editor will trigger an change event before the
  objects SaveFileSpeedButton and SaveTreeDefinitionMenuItem have been
  created. This COULD be bogus NOW}
  if SaveTreeDefFileBtn <> nil then SaveTreeDefFileBtn.Enabled := True;
  if Save1 <> nil then  Save1.Enabled := True;
  end; *)
// -----------------------------------------------------

procedure TaGlsTreeForm.LevelsNumberEditExit(Sender: TObject);
begin
  GlobalLevelsNumber := StrtoInt(LevelsNumberEdit.Text);
  If GlobalLevelsNumber > 7 then
  begin
    showmessage('Sorry! Limited to 7 Levels.');
    exit;
  end;
  if GlobalLevelsNumber <= 0 then
  begin
    MessageDlg('Levels should be a value greater than zero!', mtError,
      [mbOK], 0);
    { LevelsNumberEdit.SetFocus;
      LevelsNumberEdit.SelectAll; }
  end
  else { LevelsNumberEdit.GetValue > 0 }
  { If strtoint(LevelsNumberEdit.Text) <> CurrentLevelsNumber then }
  begin { Make some newbies  Level1TS.TabVisible:=False; }
    Level1TS.Font.Color := clGrayText;
    Level2TS.Font.Color := clGrayText;
    Level3TS.Font.Color := clGrayText;
    Level4TS.Font.Color := clGrayText;
    Level5TS.Font.Color := clGrayText;
    Level6TS.Font.Color := clGrayText;
    { hide redundant tab sheets }
    If GlobalLevelsNumber > 1 then
      Level1TS.Font.Color := clWindowText;
    if GlobalLevelsNumber > 2 then
      Level2TS.Font.Color := clWindowText;
    if GlobalLevelsNumber > 3 then
      Level3TS.Font.Color := clWindowText;
    if GlobalLevelsNumber > 4 then
      Level4TS.Font.Color := clWindowText;
    if GlobalLevelsNumber > 5 then
      Level5TS.Font.Color := clWindowText;
    if GlobalLevelsNumber > 6 then
      Level6TS.Font.Color := clWindowText;
  end;
end;

procedure TaGlsTreeForm.InitModelParameters(ModelParameters: TModelParameters);
{ Pre: ModelParameters <> nil
  Post: All model parameters inputted by the user have been assigned to
  the corresponding properties of the class FModelParameters. }
var
  i: Integer;
begin
  { Initialize the model parameters class }
  with ModelParameters do
  begin
    Shape := ShapeComboBox.ItemIndex;
    BaseSize := strtofloat(BaseSizeFloatEdit.Text);
    BaseSplits := StrtoInt(BaseSplits0NumberEdit.Text);
    Scale := strtofloat(ScaleFloatEdit.Text);
    ScaleV := strtofloat(ScaleVFloatEdit.Text);
    ZScale := strtofloat(ZScaleFloatEdit.Text);
    ZScaleV := strtofloat(ZScaleVFloatEdit.Text);

    { Levels determined upon Create
      Levelers             := Strtoint(LevelsNumberEdit.Text); }

    Ratio := strtofloat(RatioFloatEdit.Text);
    RatioPower := strtofloat(RatioPowerFloatEdit.Text);
    Lobes := StrtoInt(LobesNumberEdit.Text);
    LobeDepth := strtofloat(LobeDepthFloatEdit.Text);
    Flare := strtofloat(FlareFloatEdit.Text);
    Leaves := StrtoInt(LeavesNumberEdit.Text);
    LeafShape := LeafShapeComboBox.ItemIndex;
    LeafScale := strtofloat(LeafScaleFloatEdit.Text);
    LeafScaleX := strtofloat(LeafScaleXFloatEdit.Text);
    LeafQuality := strtofloat(LeafQualityFloatEdit.Text);
    LeafColor := LeafColorShape.Brush.Color;
    LeafColorVariation := LeafColorVariationCheckBox.Checked;
    AttractionUp := strtofloat(AttractionUpFloatEdit.Text);
    PruneRatio := strtofloat(PruneRatioFloatEdit.Text);
    PruneWidth := strtofloat(PruneWidthFloatEdit.Text);
    PruneWidthPeak := strtofloat(PruneWidthPeakFloatEdit.Text);
    PrunePowerLow := strtofloat(PrunePowerLowFloatEdit.Text);
    PrunePowerHigh := strtofloat(PrunePowerHighFloatEdit.Text);

    Scale0 := strtofloat(Scale0FloatEdit.Text);
    ScaleV0 := strtofloat(ScaleV0FloatEdit.Text);

    nLength[0] := strtofloat(Length0FloatEdit.Text);
    nLengthV[0] := strtofloat(LengthV0FloatEdit.Text);
    nTaper[0] := strtofloat(Taper0FloatEdit.Text);

    nSegSplits[0] := strtofloat(SegSplits0FloatEdit.Text);
    nSplitAngle[0] := strtofloat(SplitAngle0FloatEdit.Text);
    nSplitAngleV[0] := strtofloat(SplitAngleV0FloatEdit.Text);
    nCurveRes[0] := StrtoInt(CurveRes0NumberEdit.Text);
    nCurveBack[0] := strtofloat(CurveBack0FloatEdit.Text);
    nCurve[0] := strtofloat(Curve0FloatEdit.Text);
    nCurveV[0] := strtofloat(CurveV0FloatEdit.Text);
    nVertices[0] := StrtoInt(Vertices0NumberEdit.Text);
    // nLeaves[0]       := strtoint(Leaves0NumberEdit.Text);

    { The first is the Trunk
      The last level is reserved for the leaves, and thus doesn't include stem
      parameters (that's why the '- 1' term after Levels. }

    for i := 1 to Levelers - 1 do
    begin

      { Initialize the stem parameters for each recursion level
        using FindComponent to locate the float edit component
        corresponding with the stem parameter }

      nLength[i] :=
        strtofloat(TEdit(FindComponent('Length' + Inttostr(i) +
        'FloatEdit')).Text);
      nLengthV[i] :=
        strtofloat(TEdit(FindComponent('LengthV' + Inttostr(i) +
        'FloatEdit')).Text);
      nTaper[i] := strtofloat
        (TEdit(FindComponent('Taper' + Inttostr(i) + 'FloatEdit')).Text);
      nSegSplits[i] :=
        strtofloat(TEdit(FindComponent('SegSplits' + Inttostr(i) +
        'FloatEdit')).Text);
      nSplitAngle[i] :=
        strtofloat(TEdit(FindComponent('SplitAngle' + Inttostr(i) +
        'FloatEdit')).Text);
      nSplitAngleV[i] :=
        strtofloat(TEdit(FindComponent('SplitAngleV' + Inttostr(i) +
        'FloatEdit')).Text);
      nCurveRes[i] :=
        StrtoInt(TEdit(FindComponent('CurveRes' + Inttostr(i) +
        'NumberEdit')).Text);
      nCurveBack[i] :=
        strtofloat(TEdit(FindComponent('CurveBack' + Inttostr(i) +
        'FloatEdit')).Text);
      nCurve[i] := strtofloat
        (TEdit(FindComponent('Curve' + Inttostr(i) + 'FloatEdit')).Text);
      nCurveV[i] :=
        strtofloat(TEdit(FindComponent('CurveV' + Inttostr(i) +
        'FloatEdit')).Text);
      nRotate[i] :=
        strtofloat(TEdit(FindComponent('Rotate' + Inttostr(i) +
        'FloatEdit')).Text);
      nRotateV[i] :=
        strtofloat(TEdit(FindComponent('RotateV' + Inttostr(i) +
        'FloatEdit')).Text);
      nBranches[i] :=
        StrtoInt(TEdit(FindComponent('Branches' + Inttostr(i) +
        'NumberEdit')).Text);
      nDownAngle[i] :=
        strtofloat(TEdit(FindComponent('DownAngle' + Inttostr(i) +
        'FloatEdit')).Text);
      nDownAngleV[i] :=
        strtofloat(TEdit(FindComponent('DownAngleV' + Inttostr(i) +
        'FloatEdit')).Text);
      nVertices[i] :=
        StrtoInt(TEdit(FindComponent('Vertices' + Inttostr(i) +
        'NumberEdit')).Text);
      nLeaves[i] :=
        StrtoInt(TEdit(FindComponent('Leaves' + Inttostr(i) +
        'NumberEdit')).Text);
    end;

    { New added stuff }
    TreeSeed := StrtoInt(RandomTreeSeedNumberEdit.Text);

    Health := HealthTrackBar.Position;
    Season := SeasonComboBox.ItemIndex;

    TreeImageFile := TreeImageEdit.Text;
    TreeShapeFile := TreeShapeEdit.Text;
    TreeBarkFile := TreeBarkEdit.Text;

    TreeColor := TreeColorShape.Brush.Color;
    TreeColorVariation := TreeColorVariationCheckBox.Checked;

    Distance := DistanceTrackBar.Position;
    WindStrength := WindStrengthTB.Position;
    WindGust := WindGustTB.Position;
    WindFrom := WindFromTB.Position;
    SunHeight := SunHeightTB.Position;
    SunStrength := SunStrengthTB.Position;
    SunFrom := SunFromTB.Position;

    LeafImageFile := LeafImageEdit.Text;
    LeafShapeFile := LeafShapeEdit.Text;
    LeafTextureFile := LeafTextureEdit.Text;
    LeafLocation := LeafLocationRG.ItemIndex;
    FLeafsPer := StrtoInt(LeafsPerEdit.Text);
    LeafGrouping := LeafGroupingCB.ItemIndex;
    LeafBackColor := LeafBackColorShape.Brush.Color;
    LeafBackColorVariation := LeafBackColorVariationCheckBox.Checked;
    FruitPattern := FruitTypeRG.ItemIndex;
    FruitScale := strtofloat(FruitScaleFloatEdit.Text);
    FruitScaleX := strtofloat(FruitScaleXFloatEdit.Text);
    Fruits := StrtoInt(FruitPercentEdit.Text);
    FruitPer := StrtoInt(FruitPerEdit.Text);
    FruitLocation := FruitLocationRG.ItemIndex;
    FruitImageFile := FruitImageEdit.Text;
    FruitShapeFile := FruitShapeFileEdit.Text;
    FruitTextureFile := FruitTextureEdit.Text;
    FruitColorVariation := FruitColorVariationCheckBox.Checked;
    FruitColor := FruitColorShape.Brush.Color;

    { Adjust the current low level parameters according to
      the high level parameters }

    case SeasonComboBox.ItemIndex of
      0: { Winter }
        begin
          Leaves := 0;
          Fruits := 0;
        end;
      1: { Spring }
        begin
          LeafScale := LeafScale / 2;
          LeafScaleX := LeafScaleX / 2;
          FruitScale := FruitScale / 2;
          FruitScaleX := FruitScaleX / 2;
        end;
      { 2: Summer (no adjustment needed) }
      3: { Autumn ..turn em brown }
        begin
          LeafColor := $2A8AE4;
          LeafColorVariation := True;
          LeafBackColor := $2A8AE4;
          LeafBackColorVariation := True;
          FruitColorVariation := True;
          FruitColor := $2A8AE4;
        end;
    end;
    { This should reduce the number of Leaves iaw Health
      Done in GlsTree now... }
    { Leaves := Leaves - (Leaves * (1 - (101 div (HealthTrackBar.Position + 1)))); }
    { Leaves := (Round(Leaves *(HealthTrackBar.Position/100)));
      if (Leaves < 0) then Leaves := 0; }

  end;
end;
// -----------------------------------------------------
// -----------------------------------------------------

// -----------------------------------------------------
// -----------------------------------------------------
procedure TaGlsTreeForm.SaveTreeDefFileBtnClick(Sender: TObject);
begin
  { Update the amount of stem levels }
  LevelsNumberEditExit(Sender);
  { This procedure is used for all save actions. if the Save As menu item
    was clicked, a standard save dialog will be opened. if either the save
    speedbutton or the Save menu item was clicked the file will be saved
    immediately, unless the TreeDefFileNameEdit doesn't contain a filename. }

  if TMenuItem(Sender).Name = 'DefinitionSaveAs1' then
  begin
    GlsDefinitionPath := ExtractFilePath(TreeDefFileNameEdit.Text);
    SaveTdfDialog.Initialdir := GlsDefinitionPath;
    SaveTdfDialog.Filename := TreeDefFileNameEdit.Text;
    if SaveTdfDialog.Execute then
    begin
      Application.ProcessMessages;
      SaveTreeDefinition(SaveTdfDialog.Filename);
      TreeDefFileNameEdit.Text := SaveTdfDialog.Filename;
      GlsDefinitionPath := ExtractFilePath(TreeDefFileNameEdit.Text);
    end;
  end
  else
  begin
    if TreeDefFileNameEdit.Text = '' then
    begin
      SaveTdfDialog.Initialdir := GlsDefinitionPath;
      if SaveTdfDialog.Execute then
      begin
        Application.ProcessMessages;
        SaveTreeDefinition(SaveTdfDialog.Filename);
        TreeDefFileNameEdit.Text := SaveTdfDialog.Filename;
        GlsDefinitionPath := ExtractFilePath(TreeDefFileNameEdit.Text);
      end;
    end
    else
    begin { Cannot overwrite .trd always saves as Version 0.2 }
      SaveTreeDefinition(ChangeFileExt(TreeDefFileNameEdit.Text, '.tdf'));
      GlsDefinitionPath := ExtractFilePath(TreeDefFileNameEdit.Text);
    end;
  end;
end;

procedure TaGlsTreeForm.SaveTreeDefinition(Filename: string);
{ Pre: True
  Post: The current model parameters have been saved to FileName. }
var
  f: TextFile;
begin
  LevelsNumberEditExit(nil);
  try
    AssignFile(f, Filename);
    Rewrite(f);
    try
      { Write the header }
      Writeln(f, 'Tree Definition File V ' + TREAL_VERSION + ', generated on ' +
        DateToStr(Date) + ' by GLS TreeReal');
      Writeln(f, TREAL_VERSION);
      { Save the item indices of the comboboxes }
      Writeln(f, Inttostr(ShapeComboBox.ItemIndex));
      Writeln(f, Inttostr(LeafShapeComboBox.ItemIndex));
      { Load the values belonging to all number edit input components }
      Writeln(f, LevelsNumberEdit.Text);
      Writeln(f, LobesNumberEdit.Text);
      Writeln(f, BaseSplits0NumberEdit.Text);
      Writeln(f, CurveRes0NumberEdit.Text);
      Writeln(f, LeavesNumberEdit.Text);
      { 10 } Writeln(f, Vertices0NumberEdit.Text);
      { Save the values belonging to all float edit input components }
      Writeln(f, ScaleFloatEdit.Text);
      Writeln(f, ScaleVFloatEdit.Text);
      Writeln(f, BaseSizeFloatEdit.Text);
      Writeln(f, ZScaleFloatEdit.Text);
      Writeln(f, ZScaleVFloatEdit.Text);
      Writeln(f, RatioFloatEdit.Text);
      Writeln(f, RatioPowerFloatEdit.Text);
      Writeln(f, LobeDepthFloatEdit.Text);
      Writeln(f, FlareFloatEdit.Text);
      Writeln(f, LeafScaleFloatEdit.Text);
      Writeln(f, LeafScaleXFloatEdit.Text);
      Writeln(f, LeafQualityFloatEdit.Text);
      Writeln(f, AttractionUpFloatEdit.Text);
      Writeln(f, PruneRatioFloatEdit.Text);
      Writeln(f, PruneWidthFloatEdit.Text);
      Writeln(f, PruneWidthPeakFloatEdit.Text);
      Writeln(f, PrunePowerLowFloatEdit.Text);
      Writeln(f, PrunePowerHighFloatEdit.Text);
      Writeln(f, Scale0FloatEdit.Text);
      Writeln(f, ScaleV0FloatEdit.Text);
      Writeln(f, Length0FloatEdit.Text);
      Writeln(f, LengthV0FloatEdit.Text);
      Writeln(f, Taper0FloatEdit.Text);
      Writeln(f, SegSplits0FloatEdit.Text);
      Writeln(f, SplitAngle0FloatEdit.Text);
      Writeln(f, SplitAngleV0FloatEdit.Text);
      Writeln(f, CurveBack0FloatEdit.Text);
      Writeln(f, Curve0FloatEdit.Text);
      Writeln(f, CurveV0FloatEdit.Text);
      { 10+29=39 }
      { Save the values belonging to all number edit input components
        belonging to the stem parameters }

      { LevelsNumberEdit.GetValue - 2 is used in the following loop, since the
        last recursion level is the leaf level. So we have in fact
        LevelsNumberEdit.GetValue - 1 stem parameter tabs. }
      { Trunk0 1,2,3,4,5... Leaf 6 = 7 levels }
      if GlobalLevelsNumber > 1 then
      begin { Trunk0 1,... Leaf x = 3 levels }
        Writeln(f, Branches1NumberEdit.Text);
        Writeln(f, Vertices1NumberEdit.Text);
        Writeln(f, CurveRes1NumberEdit.Text);
      end;
      if GlobalLevelsNumber > 2 then
      begin { Trunk0 1,2... Leaf x = 4 levels }
        Writeln(f, Branches2NumberEdit.Text);
        Writeln(f, Vertices2NumberEdit.Text);
        Writeln(f, CurveRes2NumberEdit.Text);
      end;
      if GlobalLevelsNumber > 3 then
      begin { Trunk0 1,2,3... Leaf x = 5 levels }
        Writeln(f, Branches3NumberEdit.Text);
        Writeln(f, Vertices3NumberEdit.Text);
        Writeln(f, CurveRes3NumberEdit.Text);
      end;
      if GlobalLevelsNumber > 4 then
      begin { Trunk0 1,2,3,4... Leaf x = 6 levels }
        Writeln(f, Branches4NumberEdit.Text);
        Writeln(f, Vertices4NumberEdit.Text);
        Writeln(f, CurveRes4NumberEdit.Text);
      end;
      if GlobalLevelsNumber > 5 then
      begin { Trunk0 1,2,3,4,5... Leaf x = 7 levels }
        Writeln(f, Branches5NumberEdit.Text);
        Writeln(f, Vertices5NumberEdit.Text);
        Writeln(f, CurveRes5NumberEdit.Text);
      end;
      if GlobalLevelsNumber > 6 then
      begin { Trunk0 1,2,3,4,5... Leaf x = 7 levels }
        Writeln(f, Branches6NumberEdit.Text);
        Writeln(f, Vertices6NumberEdit.Text);
        Writeln(f, CurveRes6NumberEdit.Text);
      end;
      { Save the values belonging to all float edit input components
        belonging to the stem parameters }

      { LevelsNumberEdit.GetValue - 2 is used in the following loop, since the
        last recursion level is the leaf level. So we have in fact
        LevelsNumberEdit.GetValue - 1 stem parameter tabs. }
      if GlobalLevelsNumber > 1 then
      begin { Trunk0 1,... Leaf x = 3 levels  7 }
        Writeln(f, Length1FloatEdit.Text);
        Writeln(f, LengthV1FloatEdit.Text);
        Writeln(f, Taper1FloatEdit.Text);
        Writeln(f, DownAngle1FloatEdit.Text);
        Writeln(f, DownAngleV1FloatEdit.Text);
        Writeln(f, Rotate1FloatEdit.Text);
        Writeln(f, RotateV1FloatEdit.Text);
        Writeln(f, CurveBack1FloatEdit.Text);
        Writeln(f, Curve1FloatEdit.Text);
        Writeln(f, CurveV1FloatEdit.Text);
        Writeln(f, SplitAngle1FloatEdit.Text);
        Writeln(f, SplitAngleV1FloatEdit.Text);
        Writeln(f, SegSplits1FloatEdit.Text); // Yes out of order
      End;
      if GlobalLevelsNumber > 2 then
      begin { Trunk0 1,... Leaf x = 3 levels  7 }
        Writeln(f, Length2FloatEdit.Text);
        Writeln(f, LengthV2FloatEdit.Text);
        Writeln(f, Taper2FloatEdit.Text);
        Writeln(f, DownAngle2FloatEdit.Text);
        Writeln(f, DownAngleV2FloatEdit.Text);
        Writeln(f, Rotate2FloatEdit.Text);
        Writeln(f, RotateV2FloatEdit.Text);
        Writeln(f, CurveBack2FloatEdit.Text);
        Writeln(f, Curve2FloatEdit.Text);
        Writeln(f, CurveV2FloatEdit.Text);
        Writeln(f, SplitAngle2FloatEdit.Text);
        Writeln(f, SplitAngleV2FloatEdit.Text);
        Writeln(f, SegSplits2FloatEdit.Text); { Yes out of order }
      End;
      if GlobalLevelsNumber > 3 then
      begin { Trunk0 1,... Leaf x = 3 levels  7 }
        Writeln(f, Length3FloatEdit.Text);
        Writeln(f, LengthV3FloatEdit.Text);
        Writeln(f, Taper3FloatEdit.Text);
        Writeln(f, DownAngle3FloatEdit.Text);
        Writeln(f, DownAngleV3FloatEdit.Text);
        Writeln(f, Rotate3FloatEdit.Text);
        Writeln(f, RotateV3FloatEdit.Text);
        Writeln(f, CurveBack3FloatEdit.Text);
        Writeln(f, Curve3FloatEdit.Text);
        Writeln(f, CurveV3FloatEdit.Text);
        Writeln(f, SplitAngle3FloatEdit.Text);
        Writeln(f, SplitAngleV3FloatEdit.Text);
        Writeln(f, SegSplits3FloatEdit.Text); { Yes out of order }
      End;
      if GlobalLevelsNumber > 4 then
      begin // Trunk0 1,... Leaf x = 3 levels  7
        Writeln(f, Length4FloatEdit.Text);
        Writeln(f, LengthV4FloatEdit.Text);
        Writeln(f, Taper4FloatEdit.Text);
        Writeln(f, DownAngle4FloatEdit.Text);
        Writeln(f, DownAngleV4FloatEdit.Text);
        Writeln(f, Rotate4FloatEdit.Text);
        Writeln(f, RotateV4FloatEdit.Text);
        Writeln(f, CurveBack4FloatEdit.Text);
        Writeln(f, Curve4FloatEdit.Text);
        Writeln(f, CurveV4FloatEdit.Text);
        Writeln(f, SplitAngle4FloatEdit.Text);
        Writeln(f, SplitAngleV4FloatEdit.Text);
        Writeln(f, SegSplits4FloatEdit.Text); { Yes out of order }
      End;
      if GlobalLevelsNumber > 5 then
      begin { Trunk0 1,... Leaf x = 3 levels  7 }
        Writeln(f, Length5FloatEdit.Text);
        Writeln(f, LengthV5FloatEdit.Text);
        Writeln(f, Taper5FloatEdit.Text);
        Writeln(f, DownAngle5FloatEdit.Text);
        Writeln(f, DownAngleV5FloatEdit.Text);
        Writeln(f, Rotate5FloatEdit.Text);
        Writeln(f, RotateV5FloatEdit.Text);
        Writeln(f, CurveBack5FloatEdit.Text);
        Writeln(f, Curve5FloatEdit.Text);
        Writeln(f, CurveV5FloatEdit.Text);
        Writeln(f, SplitAngle5FloatEdit.Text);
        Writeln(f, SplitAngleV5FloatEdit.Text);
        Writeln(f, SegSplits5FloatEdit.Text); { Yes out of order }
      End;
      if GlobalLevelsNumber > 6 then
      begin { Trunk0 1,... Leaf x = 3 levels  7 }
        Writeln(f, Length6FloatEdit.Text);
        Writeln(f, LengthV6FloatEdit.Text);
        Writeln(f, Taper6FloatEdit.Text);
        Writeln(f, DownAngle6FloatEdit.Text);
        Writeln(f, DownAngleV6FloatEdit.Text);
        Writeln(f, Rotate6FloatEdit.Text);
        Writeln(f, RotateV6FloatEdit.Text);
        Writeln(f, CurveBack6FloatEdit.Text);
        Writeln(f, Curve6FloatEdit.Text);
        Writeln(f, CurveV6FloatEdit.Text);
        Writeln(f, SplitAngle6FloatEdit.Text);
        Writeln(f, SplitAngleV6FloatEdit.Text);
        Writeln(f, SegSplits6FloatEdit.Text); { Yes out of order }
      End;
      { Finally, save the leaf color, and the leaf color variation boolean }
      Writeln(f, Inttostr(LeafColorShape.Brush.Color));
      if LeafColorVariationCheckBox.Checked then
        Writeln(f, 'true')
      else
        Writeln(f, 'false');
      { NOW Write ALL the new data }
      Writeln(f, 'V 0.2 New stuff');
      Writeln(f, RandomTreeSeedNumberEdit.Text);
      Writeln(f, Inttostr(HealthTrackBar.Position));
      Writeln(f, Inttostr(SeasonComboBox.ItemIndex));

      Writeln(f, TreeImageEdit.Text);
      Writeln(f, TreeShapeEdit.Text);
      Writeln(f, TreeBarkEdit.Text);
      Writeln(f, Inttostr(TreeColorShape.Brush.Color));
      if TreeColorVariationCheckBox.Checked then
        Writeln(f, 'true')
      else
        Writeln(f, 'false');
      Writeln(f, Inttostr(DistanceTrackBar.Position));
      Writeln(f, Inttostr(WindStrengthTB.Position));
      Writeln(f, Inttostr(WindGustTB.Position));
      Writeln(f, Inttostr(WindFromTB.Position));
      Writeln(f, Inttostr(SunHeightTB.Position));
      Writeln(f, Inttostr(SunStrengthTB.Position));
      Writeln(f, Inttostr(SunFromTB.Position));
      Writeln(f, LeafImageEdit.Text);
      Writeln(f, LeafShapeEdit.Text);
      Writeln(f, LeafTextureEdit.Text);
      Writeln(f, Inttostr(LeafLocationRG.ItemIndex));
      Writeln(f, LeafsPerEdit.Text);
      Writeln(f, Inttostr(LeafGroupingCB.ItemIndex));
      Writeln(f, Inttostr(LeafBackColorShape.Brush.Color));
      if LeafBackColorVariationCheckBox.Checked then
        Writeln(f, 'true')
      else
        Writeln(f, 'false');
      Writeln(f, Inttostr(FruitTypeRG.ItemIndex));
      Writeln(f, LeafScaleFloatEdit.Text);
      Writeln(f, LeafScaleXFloatEdit.Text);
      Writeln(f, FruitPercentEdit.Text);
      Writeln(f, FruitPerEdit.Text);
      Writeln(f, Inttostr(FruitLocationRG.ItemIndex));
      Writeln(f, FruitImageEdit.Text);
      Writeln(f, FruitShapeFileEdit.Text);
      Writeln(f, FruitTextureEdit.Text);

      if FruitColorVariationCheckBox.Checked then
        Writeln(f, 'true')
      else
        Writeln(f, 'false');
      Writeln(f, Inttostr(FruitColorShape.Brush.Color));

      Writeln(f, Leaves0NumberEdit.Text);
      Writeln(f, Leaves1NumberEdit.Text);
      Writeln(f, Leaves2NumberEdit.Text);
      Writeln(f, Leaves3NumberEdit.Text);
      Writeln(f, Leaves4NumberEdit.Text);
      Writeln(f, Leaves5NumberEdit.Text);
      Writeln(f, Leaves6NumberEdit.Text);
    except
      { On known exceptions show an error message. }
      on EConvertError do
        MessageDlg(Filename + ' is not a valid tree definition file!', mtError,
          [mbOK], 0);
      on EInOutError do
        MessageDlg('Error while writing ' + Filename + '!', mtError, [mbOK], 0);

      else
        { Show a general error message }
        MessageDlg('Unknow error while writing ' + Filename + '!', mtError,
          [mbOK], 0);
    end;
  finally
    CloseFile(f);
  end;
end;

// -----------------------------------------------------
{ None Blooms Nuts Green Ripe }
// -----------------------------------------------------
procedure TaGlsTreeForm.OpenTreeDefFileBtnClick(Sender: TObject);
begin { tree definitions }
  { OpenTdfDialog.FileName:='*.*'; }
  OpenTdfDialog.Initialdir := ExtractFilePath(ParamStr(0)) + 'tree definitions';
  { GlsDefinitionPath:=ExtractFilePath(TreeDefFileNameEdit.Text);
    OpenTdfDialog.InitialDir:= GlsDefinitionPath; }
  if OpenTdfDialog.Execute then
  begin
    Application.ProcessMessages;
    TreeDefFileNameEdit.Text := OpenTdfDialog.Filename;
    GlsDefinitionPath := ExtractFilePath(TreeDefFileNameEdit.Text);
    LoadTreeDefinition(OpenTdfDialog.Filename);
  end;
end;

procedure TaGlsTreeForm.LoadTreeDefinition(Filename: string);
{ Pre: FileName should point to an existing file.
  Post: The current model parameters have been set to the model parameters
  loaded from the tree definition file FileName. }
var
  f: TextFile;
  Newbie: Boolean;
  { i, j: integer; }
  s: String;
  function GetNextValue: string;
  { Pre: f is assigned to a valid tree definition file.
    Ret: The next model parameter value read from f. }
  var
    Dummy: string;
  begin
    Readln(f, Dummy);
    Result := Dummy;
  end;

begin
  Newbie := False;
  try
    AssignFile(f, Filename);
    Reset(f);
    { Skip the header, 2nd line of text is version for changes }
    Readln(f, s);
    Readln(f, s);
    if s = TREAL_VERSION then
      Newbie := True;
    try
      { Update the tree definition filename edit box }
      TreeDefFileNameEdit.Text := Filename;
      { Save the item indices of the comboboxes }
      ShapeComboBox.ItemIndex := StrtoInt(GetNextValue);
      LeafShapeComboBox.ItemIndex := StrtoInt(GetNextValue);
      { Load the values belonging to all number edit input components }
      LevelsNumberEdit.Text := GetNextValue;
      GlobalLevelsNumber := StrtoInt(LevelsNumberEdit.Text);
      { Levels := CurrentLevelsNumber; }
      LevelsNumberEditExit(nil);
      LobesNumberEdit.Text := GetNextValue;
      BaseSplits0NumberEdit.Text := GetNextValue;
      CurveRes0NumberEdit.Text := GetNextValue;
      LeavesNumberEdit.Text := GetNextValue;
      Vertices0NumberEdit.Text := GetNextValue;
      { Save the values belonging to all float edit input components }
      ScaleFloatEdit.Text := GetNextValue;
      ScaleVFloatEdit.Text := GetNextValue;
      BaseSizeFloatEdit.Text := GetNextValue;
      ZScaleFloatEdit.Text := GetNextValue;
      ZScaleVFloatEdit.Text := GetNextValue;
      RatioFloatEdit.Text := GetNextValue;
      RatioPowerFloatEdit.Text := GetNextValue;
      LobeDepthFloatEdit.Text := GetNextValue;
      FlareFloatEdit.Text := GetNextValue;
      LeafScaleFloatEdit.Text := GetNextValue;
      LeafScaleXFloatEdit.Text := GetNextValue;
      LeafQualityFloatEdit.Text := GetNextValue;
      AttractionUpFloatEdit.Text := GetNextValue;
      PruneRatioFloatEdit.Text := GetNextValue;
      PruneWidthFloatEdit.Text := GetNextValue;
      PruneWidthPeakFloatEdit.Text := GetNextValue;
      PrunePowerLowFloatEdit.Text := GetNextValue;
      PrunePowerHighFloatEdit.Text := GetNextValue;
      Scale0FloatEdit.Text := GetNextValue;
      ScaleV0FloatEdit.Text := GetNextValue;
      Length0FloatEdit.Text := GetNextValue;
      LengthV0FloatEdit.Text := GetNextValue;
      Taper0FloatEdit.Text := GetNextValue;
      SegSplits0FloatEdit.Text := GetNextValue;
      SplitAngle0FloatEdit.Text := GetNextValue;
      SplitAngleV0FloatEdit.Text := GetNextValue;
      CurveBack0FloatEdit.Text := GetNextValue;
      Curve0FloatEdit.Text := GetNextValue;
      CurveV0FloatEdit.Text := GetNextValue;
      { Save the values belonging to all number edit input components
        belonging to the stem parameters }
      LevelsNumberEditExit(nil);
      { LevelsNumberEdit.GetValue - 2 is used in the following loop, since the
        last recursion level is the leaf level. So we have in fact
        LevelsNumberEdit.GetValue - 1 stem parameter tabs. }
      { Trunk0 1,2,3,4,5... Leaf 6 = 7 levels }
      if GlobalLevelsNumber > 1 then
      begin { Trunk0 1,... Leaf x = 3 levels }
        Branches1NumberEdit.Text := GetNextValue;
        Vertices1NumberEdit.Text := GetNextValue;
        CurveRes1NumberEdit.Text := GetNextValue;
      end;
      if GlobalLevelsNumber > 2 then
      begin { Trunk0 1,2... Leaf x = 4 levels }
        Branches2NumberEdit.Text := GetNextValue;
        Vertices2NumberEdit.Text := GetNextValue;
        CurveRes2NumberEdit.Text := GetNextValue;
      end;
      if GlobalLevelsNumber > 3 then
      begin { Trunk0 1,2,3... Leaf x = 5 levels }
        Branches3NumberEdit.Text := GetNextValue;
        Vertices3NumberEdit.Text := GetNextValue;
        CurveRes3NumberEdit.Text := GetNextValue;
      end;
      if GlobalLevelsNumber > 4 then
      begin { Trunk0 1,2,3,4... Leaf x = 6 levels }
        Branches4NumberEdit.Text := GetNextValue;
        Vertices4NumberEdit.Text := GetNextValue;
        CurveRes4NumberEdit.Text := GetNextValue;
      end;
      if GlobalLevelsNumber > 5 then
      begin { Trunk0 1,2,3,4,5... Leaf x = 7 levels }
        Branches5NumberEdit.Text := GetNextValue;
        Vertices5NumberEdit.Text := GetNextValue;
        CurveRes5NumberEdit.Text := GetNextValue;
      end;
      if GlobalLevelsNumber > 6 then
      begin { Trunk0 1,2,3,4,5... Leaf x = 7 levels }
        Branches6NumberEdit.Text := GetNextValue;
        Vertices6NumberEdit.Text := GetNextValue;
        CurveRes6NumberEdit.Text := GetNextValue;
      end;
      { Save the values belonging to all float edit input components
        belonging to the stem parameters }

      { LevelsNumberEdit.GetValue - 2 is used in the following loop, since the
        last recursion level is the leaf level. So we have in fact
        LevelsNumberEdit.GetValue - 1 stem parameter tabs. }
      if GlobalLevelsNumber > 1 then
      begin { Trunk0 1,... Leaf x = 3 levels  7 }
        Length1FloatEdit.Text := GetNextValue;
        LengthV1FloatEdit.Text := GetNextValue;
        Taper1FloatEdit.Text := GetNextValue;
        DownAngle1FloatEdit.Text := GetNextValue;
        DownAngleV1FloatEdit.Text := GetNextValue;
        Rotate1FloatEdit.Text := GetNextValue;
        RotateV1FloatEdit.Text := GetNextValue;
        CurveBack1FloatEdit.Text := GetNextValue;
        Curve1FloatEdit.Text := GetNextValue;
        CurveV1FloatEdit.Text := GetNextValue;
        SplitAngle1FloatEdit.Text := GetNextValue;
        SplitAngleV1FloatEdit.Text := GetNextValue;
        SegSplits1FloatEdit.Text := GetNextValue; { Yes out of order }
      End;
      if GlobalLevelsNumber > 2 then
      begin { Trunk0 1,... Leaf x = 3 levels  7 }
        Length2FloatEdit.Text := GetNextValue;
        LengthV2FloatEdit.Text := GetNextValue;
        Taper2FloatEdit.Text := GetNextValue;
        DownAngle2FloatEdit.Text := GetNextValue;
        DownAngleV2FloatEdit.Text := GetNextValue;
        Rotate2FloatEdit.Text := GetNextValue;
        RotateV2FloatEdit.Text := GetNextValue;
        CurveBack2FloatEdit.Text := GetNextValue;
        Curve2FloatEdit.Text := GetNextValue;
        CurveV2FloatEdit.Text := GetNextValue;
        SplitAngle2FloatEdit.Text := GetNextValue;
        SplitAngleV2FloatEdit.Text := GetNextValue;
        SegSplits2FloatEdit.Text := GetNextValue; { Yes out of order }
      End;
      if GlobalLevelsNumber > 3 then
      begin { Trunk0 1,... Leaf x = 3 levels  7 }
        Length3FloatEdit.Text := GetNextValue;
        LengthV3FloatEdit.Text := GetNextValue;
        Taper3FloatEdit.Text := GetNextValue;
        DownAngle3FloatEdit.Text := GetNextValue;
        DownAngleV3FloatEdit.Text := GetNextValue;
        Rotate3FloatEdit.Text := GetNextValue;
        RotateV3FloatEdit.Text := GetNextValue;
        CurveBack3FloatEdit.Text := GetNextValue;
        Curve3FloatEdit.Text := GetNextValue;
        CurveV3FloatEdit.Text := GetNextValue;
        SplitAngle3FloatEdit.Text := GetNextValue;
        SplitAngleV3FloatEdit.Text := GetNextValue;
        SegSplits3FloatEdit.Text := GetNextValue; { Yes out of order }
      End;
      if GlobalLevelsNumber > 4 then
      begin { Trunk0 1,... Leaf x = 3 levels  7 }
        Length4FloatEdit.Text := GetNextValue;
        LengthV4FloatEdit.Text := GetNextValue;
        Taper4FloatEdit.Text := GetNextValue;
        DownAngle4FloatEdit.Text := GetNextValue;
        DownAngleV4FloatEdit.Text := GetNextValue;
        Rotate4FloatEdit.Text := GetNextValue;
        RotateV4FloatEdit.Text := GetNextValue;
        CurveBack4FloatEdit.Text := GetNextValue;
        Curve4FloatEdit.Text := GetNextValue;
        CurveV4FloatEdit.Text := GetNextValue;
        SplitAngle4FloatEdit.Text := GetNextValue;
        SplitAngleV4FloatEdit.Text := GetNextValue;
        SegSplits4FloatEdit.Text := GetNextValue; { Yes out of order }
      End;
      if GlobalLevelsNumber > 5 then
      begin { Trunk0 1,... Leaf x = 3 levels  7 }
        Length5FloatEdit.Text := GetNextValue;
        LengthV5FloatEdit.Text := GetNextValue;
        Taper5FloatEdit.Text := GetNextValue;
        DownAngle5FloatEdit.Text := GetNextValue;
        DownAngleV5FloatEdit.Text := GetNextValue;
        Rotate5FloatEdit.Text := GetNextValue;
        RotateV5FloatEdit.Text := GetNextValue;
        CurveBack5FloatEdit.Text := GetNextValue;
        Curve5FloatEdit.Text := GetNextValue;
        CurveV5FloatEdit.Text := GetNextValue;
        SplitAngle5FloatEdit.Text := GetNextValue;
        SplitAngleV5FloatEdit.Text := GetNextValue;
        SegSplits5FloatEdit.Text := GetNextValue; { Yes out of order }
      End;
      if GlobalLevelsNumber > 6 then
      begin { Trunk0 1,... Leaf x = 3 levels  7 }
        Length6FloatEdit.Text := GetNextValue;
        LengthV6FloatEdit.Text := GetNextValue;
        Taper6FloatEdit.Text := GetNextValue;
        DownAngle6FloatEdit.Text := GetNextValue;
        DownAngleV6FloatEdit.Text := GetNextValue;
        Rotate6FloatEdit.Text := GetNextValue;
        RotateV6FloatEdit.Text := GetNextValue;
        CurveBack6FloatEdit.Text := GetNextValue;
        Curve6FloatEdit.Text := GetNextValue;
        CurveV6FloatEdit.Text := GetNextValue;
        SplitAngle6FloatEdit.Text := GetNextValue;
        SplitAngleV6FloatEdit.Text := GetNextValue;
        SegSplits6FloatEdit.Text := GetNextValue; { Yes out of order }
      End;

      { Finally, save the leaf color, and the leaf color variation boolean }
      LeafColorShape.Brush.Color := StrtoInt(GetNextValue);
      if 'true' = GetNextValue then
        LeafColorVariationCheckBox.Checked := True
      else
        LeafColorVariationCheckBox.Checked := False;
      { Version 0.2 contains some MORE data }
      if Newbie then
      begin
        Readln(f, s); { Line that says this is new stuff }
        { NOW Write ALL the new data }
        RandomTreeSeedNumberEdit.Text := GetNextValue;
        HealthTrackBar.Position := StrtoInt(GetNextValue);
        SeasonComboBox.ItemIndex := StrtoInt(GetNextValue);
        TreeImageEdit.Text := GetNextValue;
        TreeShapeEdit.Text := GetNextValue;
        TreeBarkEdit.Text := GetNextValue;
        TreeColorShape.Brush.Color := StrtoInt(GetNextValue);
        if 'true' = GetNextValue then
          TreeColorVariationCheckBox.Checked := True
        else
          TreeColorVariationCheckBox.Checked := False;
        { BarkTVWNumberEdit.Text:= GetNextValue; }
        DistanceTrackBar.Position := StrtoInt(GetNextValue);
        WindStrengthTB.Position := StrtoInt(GetNextValue);
        WindGustTB.Position := StrtoInt(GetNextValue);
        WindFromTB.Position := StrtoInt(GetNextValue);
        SunHeightTB.Position := StrtoInt(GetNextValue);
        SunStrengthTB.Position := StrtoInt(GetNextValue);
        SunFromTB.Position := StrtoInt(GetNextValue);
        { BaseFlareVFloatEdit.Text:= GetNextValue; }

        LeafImageEdit.Text := GetNextValue;
        LeafShapeEdit.Text := GetNextValue;
        LeafTextureEdit.Text := GetNextValue;
        if FileExists(LeafShapeEdit.Text) then
          LoadLeafShape(LeafShapeEdit.Text, 1)
        else
        begin
          LeafShapeEdit.Text := '';
          LeafTextureEdit.Text := '';
        end;
        LeafLocationRG.ItemIndex := StrtoInt(GetNextValue);
        LeafsPerEdit.Text := GetNextValue;
        LeafGroupingCB.ItemIndex := StrtoInt(GetNextValue);
        LeafBackColorShape.Brush.Color := StrtoInt(GetNextValue);
        if 'true' = GetNextValue then
          LeafBackColorVariationCheckBox.Checked := True
        else
          LeafBackColorVariationCheckBox.Checked := False;
        FruitTypeRG.ItemIndex := StrtoInt(GetNextValue);
        FruitScaleFloatEdit.Text := GetNextValue;
        FruitScaleXFloatEdit.Text := GetNextValue;
        FruitPercentEdit.Text := GetNextValue;
        FruitPerEdit.Text := GetNextValue;
        FruitLocationRG.ItemIndex := StrtoInt(GetNextValue);
        FruitImageEdit.Text := GetNextValue;
        FruitShapeFileEdit.Text := GetNextValue;
        FruitTextureEdit.Text := GetNextValue;
        if FileExists(FruitShapeFileEdit.Text) then
          LoadFruitShape(FruitShapeFileEdit.Text)
        else
        begin
          FruitShapeFileEdit.Text := '';
          FruitTextureEdit.Text := '';
        end;
        if 'true' = GetNextValue then
          FruitColorVariationCheckBox.Checked := True
        else
          FruitColorVariationCheckBox.Checked := False;
        FruitColorShape.Brush.Color := StrtoInt(GetNextValue);
      end;

      Leaves0NumberEdit.Text := GetNextValue;
      Leaves1NumberEdit.Text := GetNextValue;
      Leaves2NumberEdit.Text := GetNextValue;
      Leaves3NumberEdit.Text := GetNextValue;
      Leaves4NumberEdit.Text := GetNextValue;
      Leaves5NumberEdit.Text := GetNextValue;
      Leaves6NumberEdit.Text := GetNextValue;

      { of Version 0.2 added data }
    except
      { On known exceptions show an error message. }
      on EConvertError do
        MessageDlg(Filename + ' is not a valid tree definition file!', mtError,
          [mbOK], 0);
      on EInOutError do
        MessageDlg('Error while reading ' + Filename + '!', mtError, [mbOK], 0);
      else
        { Show a general error message }
        MessageDlg('Unknow error while reading ' + Filename + '!', mtError,
          [mbOK], 0);
    end;
  finally
    CloseFile(f);
  end;
end;

// -----------------------------------------------------
// -----------------------------------------------------

procedure TaGlsTreeForm.SetupPrinterBtnClick(Sender: TObject);
begin
  PrinterSetupDialog.Execute;
end;

procedure TaGlsTreeForm.SaveAnnoDefinitionBtnClick(Sender: TObject);
begin
  SaveOrPrint(0);
end;

procedure TaGlsTreeForm.PrintTreeDefFileBtnClick(Sender: TObject);
begin
  SaveOrPrint(1);
end;

procedure TaGlsTreeForm.SaveOrPrint(Switch: Integer);
var
  s: String;
  i, RunningCount: Integer;
begin
  if FileExists(TreeDefFileNameEdit.Text) then
  begin
    if Switch = 0 then
      RichEdit1.PlainText := True;
    Application.ProcessMessages;
    RichEdit1.Clear;
    { Load info to hidden RichEdit and print IT }
    RichEdit1.Lines.LoadfromFile(TreeDefFileNameEdit.Text);
    RichEdit1.Lines.Insert(0, ''); { Add Title }
    RichEdit1.Lines.Insert(0, TreeDefFileNameEdit.Text);
    { Put 3 blank lines at TOP to move down }
    RichEdit1.Lines.Insert(0, '');
    RichEdit1.Lines.Insert(0, '');
    RichEdit1.Lines.Insert(0, '');
    s := RichEdit1.Lines[7];
    RichEdit1.Lines[7] := 'Shape: ' + s;
    s := RichEdit1.Lines[8];
    RichEdit1.Lines[8] := 'LeafShape: ' + s;
    s := RichEdit1.Lines[9];
    RichEdit1.Lines[9] := 'Levels: ' + s;
    s := RichEdit1.Lines[10];
    RichEdit1.Lines[10] := 'Lobes: ' + s;
    s := RichEdit1.Lines[11];
    RichEdit1.Lines[11] := 'BaseSplits 0: ' + s;
    s := RichEdit1.Lines[12];
    RichEdit1.Lines[12] := 'CurveRes 0: ' + s;
    s := RichEdit1.Lines[13];
    RichEdit1.Lines[13] := 'Leaves: ' + s;
    s := RichEdit1.Lines[14];
    RichEdit1.Lines[14] := 'Vertices 0: ' + s;
    s := RichEdit1.Lines[15];
    RichEdit1.Lines[15] := 'Scale: ' + s;
    s := RichEdit1.Lines[16];
    RichEdit1.Lines[16] := 'ScaleV: ' + s;
    s := RichEdit1.Lines[17];
    RichEdit1.Lines[17] := 'BaseSize: ' + s;
    s := RichEdit1.Lines[18];
    RichEdit1.Lines[18] := 'ZScale: ' + s;
    s := RichEdit1.Lines[19];
    RichEdit1.Lines[19] := 'ZScale V: ' + s;
    s := RichEdit1.Lines[20];
    RichEdit1.Lines[20] := 'Ratio: ' + s;
    s := RichEdit1.Lines[21];
    RichEdit1.Lines[21] := 'Ratio Power: ' + s;
    s := RichEdit1.Lines[22];
    RichEdit1.Lines[22] := 'Lobe Depth: ' + s;
    s := RichEdit1.Lines[23];
    RichEdit1.Lines[23] := 'Flare: ' + s;
    s := RichEdit1.Lines[24];
    RichEdit1.Lines[24] := 'LeafScale: ' + s;
    s := RichEdit1.Lines[25];
    RichEdit1.Lines[25] := 'LeafScale X: ' + s;
    s := RichEdit1.Lines[26];
    RichEdit1.Lines[26] := 'Leaf Quality: ' + s;
    s := RichEdit1.Lines[27];
    RichEdit1.Lines[27] := 'AttractionUp: ' + s;
    s := RichEdit1.Lines[28];
    RichEdit1.Lines[28] := 'Prune Ratio: ' + s;
    s := RichEdit1.Lines[29];
    RichEdit1.Lines[29] := 'Prune Width: ' + s;
    s := RichEdit1.Lines[30];
    RichEdit1.Lines[30] := 'Prune Width Peak: ' + s;
    s := RichEdit1.Lines[31];
    RichEdit1.Lines[31] := 'Prune Power Low: ' + s;
    s := RichEdit1.Lines[32];
    RichEdit1.Lines[32] := 'PrunePowerHigh: ' + s;
    s := RichEdit1.Lines[33];
    RichEdit1.Lines[33] := 'Scale0: ' + s;
    s := RichEdit1.Lines[34];
    RichEdit1.Lines[34] := 'ScaleV0: ' + s;
    s := RichEdit1.Lines[35];
    RichEdit1.Lines[35] := 'Length0: ' + s;
    s := RichEdit1.Lines[36];
    RichEdit1.Lines[36] := 'LengthV0: ' + s;
    s := RichEdit1.Lines[37];
    RichEdit1.Lines[37] := 'Taper0: ' + s;
    s := RichEdit1.Lines[38];
    RichEdit1.Lines[38] := 'SegSplits0: ' + s;
    s := RichEdit1.Lines[39];
    RichEdit1.Lines[39] := 'SplitAngle0: ' + s;
    s := RichEdit1.Lines[40];
    RichEdit1.Lines[40] := 'SplitAngleV0: ' + s;
    s := RichEdit1.Lines[41];
    RichEdit1.Lines[41] := 'CurveBack0: ' + s;
    s := RichEdit1.Lines[42];
    RichEdit1.Lines[42] := 'Curve0: ' + s;
    s := RichEdit1.Lines[43];
    RichEdit1.Lines[43] := 'CurveV0: ' + s;
    RunningCount := 43;
    For i := 1 to GlobalLevelsNumber - 1 do
    begin { Trunk0 1,... Leaf x = 3 levels }
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Branches' + Inttostr(i) + ': ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Vertices' + Inttostr(i) + ': ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'CurveRes' + Inttostr(i) + ': ' + s;
    end;
    { Trunk0 1,... Leaf x = 3 levels  7 }
    For i := 1 to GlobalLevelsNumber - 1 do
    begin
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Length' + Inttostr(i) + ': ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'LengthV' + Inttostr(i) + ': ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Taper' + Inttostr(i) + ': ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'DownAngle' + Inttostr(i) + ': ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'DownAngleV' + Inttostr(i) + ': ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Rotate' + Inttostr(i) + ': ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'RotateV' + Inttostr(i) + ': ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'CurveBack' + Inttostr(i) + ': ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Curve' + Inttostr(i) + ': ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'CurveV' + Inttostr(i) + ': ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'SplitAngle' + Inttostr(i) + ': ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'SplitAngleV' + Inttostr(i) + ': ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'SegSplits' + Inttostr(i) + ': ' + s;
    End;
    inc(RunningCount);
    s := RichEdit1.Lines[RunningCount];
    RichEdit1.Lines[RunningCount] := 'LeafColor: ' + s;
    inc(RunningCount);
    s := RichEdit1.Lines[RunningCount];
    RichEdit1.Lines[RunningCount] := 'LeafColorVariation: ' + s;
    { Old files would NOT have the new stuff -5  for sure! }
    if (RunningCount < RichEdit1.Lines.Count - 5) then
    begin
      inc(RunningCount); { Line Skip }

      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'TreeSeed: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Health: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Season: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'TreeImageFile: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'TreeShapeFile: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'TreeBarkFile: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'TreeColor: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'TreeColorVariation: ' + s;
      { inc(RunningCount);
        s:=RichEdit1.Lines[RunningCount];
        RichEdit1.Lines[RunningCount] := 'Bark Texture Vertical Wrap:: '+s; }
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Distance: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'WindStrength: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'WindGust: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'WindFrom: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'SunHeight: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'SunStrength: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'SunFrom: ' + s;
      { inc(RunningCount);
        s:=RichEdit1.Lines[RunningCount];
        RichEdit1.Lines[RunningCount] := 'BaseFlare: '+s; }
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'LeafImageFile: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'LeafShapeFile: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'LeafTextureFile: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'LeafLocation: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'FLeafsPer: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'LeafGrouping: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'LeafBackColor: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'LeafBackColorVariation: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Fruit Pattern: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Fruit Scale: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Fruit Scale X: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Fruit #: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'FruitPer: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'FruitLocation: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'FruitImageFile: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'FruitShapeFile: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'FruitTextureFile: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'FruitColorVariation: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'FruitColor: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Leaves @0: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Leaves @1: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Leaves @2: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Leaves @3: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Leaves @4: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Leaves @5: ' + s;
      inc(RunningCount);
      s := RichEdit1.Lines[RunningCount];
      RichEdit1.Lines[RunningCount] := 'Leaves @6: ' + s;
    end;
    if Switch = 0 then
      RichEdit1.Lines.Savetofile
        (ChangeFileExt(TreeDefFileNameEdit.Text, '.txt'))
    else if Switch = 1 then
      RichEdit1.Print(TreeDefFileNameEdit.Text);
    Application.ProcessMessages;
    RichEdit1.Clear;
  end;
end;
// -----------------------------------------------------
// -----------------------------------------------------

// -----------------------------------------------------
// -----------------------------------------------------
procedure TaGlsTreeForm.LoadTreeImageBtnClick(Sender: TObject);
var
  s: String;
Begin
  s := TreeImageEdit.Text;
  if LoadImage(s) then
  begin
    TreeImageEdit.Text := s;
    TreeImageLoaded := True;
    LeafImageLoaded := False;
    FruitImageLoaded := False;
    ImageLoaded := True;
  end
  else
    TreeImageEdit.Text := '';
End;

Function TaGlsTreeForm.LoadImage(var InName: String): Boolean;
var
  BitmapLoaded: Boolean;
  BitMap: TBitmap;
  jp: TJpegImage;
  PNG: TPNGObject;
  tga: TTGAImage;
  s: String;
begin
  BitmapLoaded := False;
  OpenPictureDialog1.Filename := InName;
  OpenPictureDialog1.Initialdir := GlsImagePath;
  if OpenPictureDialog1.Execute then
  begin
    TreeImageLoaded := False; { Set these false so ONLY 1 can be edited }
    LeafImageLoaded := False;
    FruitImageLoaded := False;
    ImageLoaded := False;
    GlsImagePath := ExtractFilePath(OpenPictureDialog1.Filename);
    BitmapLoaded := True;
    InName := OpenPictureDialog1.Filename;
    s := lowercase(ExtractFileExt(OpenPictureDialog1.Filename));
    BitMap := TBitmap.Create; { all get assigned to it }
    try
      if s = '.bmp' then
        BitMap.LoadfromFile(OpenPictureDialog1.Filename)
      else if s = '.png' then
      begin
        PNG := TPNGObject.Create;
        try
          PNG.LoadfromFile(OpenPictureDialog1.Filename);
          BitMap.Assign(PNG); // Convert data into bitmap
        finally
          PNG.Free;
        end;
      end
      else if s = '.tga' then
      begin
        tga := TTGAImage.Create;
        try
          tga.LoadfromFile(OpenPictureDialog1.Filename);
          BitMap.Width := tga.Width;
          BitMap.Height := tga.Height;
          BitMap.Canvas.Draw(0, 0, tga);
          { tga.Assign(pic.Bitmap);
            tga.SaveToFile(fName) }
        finally
          tga.Free;
        end;
      end
      else if s = '.jpg' then
      begin
        jp := TJpegImage.Create;
        try
          with jp do
          begin
            jp.LoadfromFile(OpenPictureDialog1.Filename);
            BitMap.Width := jp.Width;
            BitMap.Height := jp.Height;
            BitMap.Canvas.Draw(0, 0, jp);
          end;
        finally
          jp.Free;
        end;
      end
      else
      begin
        BitmapLoaded := False;
        showmessage('bmp, png, jpg else:' + #13#10 +
          'File format not supported');
      end;
      if BitmapLoaded = True then
      begin
        TracerImage.Width := BitMap.Width;
        TracerImage.Height := BitMap.Height;
        TracerImage.Picture.Assign(BitMap);
        GrabberImageBitmap.Width := BitMap.Width;
        GrabberImageBitmap.Height := BitMap.Height;
        GrabberImageBitmap.Assign(BitMap);
      end;
    finally
      BitMap.Free;
    end;
  end;
  Result := BitmapLoaded;
end;

procedure TaGlsTreeForm.LoadTreeShapeBtnClick(Sender: TObject);
var
  f: TextFile;
  Incrementer, i: Integer;
  ss, s: string;
begin { GlsShapePath }
  { Shape file (tsf, lsf, fsf) }
  OpenShapeDialog.Initialdir := GlsShapePath;
  if OpenShapeDialog.Execute then
  begin
    LeafShapeEdit.Text := OpenShapeDialog.Filename;
    GlsShapePath := ExtractFilePath(LeafShapeEdit.Text);
    try
      AssignFile(f, OpenShapeDialog.Filename);
      Reset(f);
      try
        For Incrementer := 0 to 4 do
        Begin
          Readln(f, s);
          TreePolygonVerticesNumber[Incrementer] := StrtoInt(s);
          SetLength(TreePolygonVertices[Incrementer],
            TreePolygonVerticesNumber[Incrementer] + 1, 3);
          SetLength(TreePolyImageVertices[Incrementer],
            TreePolygonVerticesNumber[Incrementer] + 1, 2);
          For i := 0 to TreePolygonVerticesNumber[Incrementer] do
          begin { FruitPolyImageVertices }
            Readln(f, s);
            ss := Copy(s, 0, Pos(',', s) - 1);
            TreePolyImageVertices[Incrementer, i, 0] := StrtoInt(ss);
            ss := '';
            ss := Copy(s, Pos(',', s) + 1, Length(s));
            s := ss;
            ss := '';
            ss := Copy(s, 0, Pos(',', s) - 1);
            TreePolyImageVertices[Incrementer, i, 1] := StrtoInt(ss);
            ss := '';
            ss := Copy(s, Pos(',', s) + 1, Length(s));
            s := ss;
            ss := '';
            ss := Copy(s, 0, Pos(',', s) - 1);
            TreePolygonVertices[Incrementer, i, 0] := strtofloat(ss);
            ss := '';
            ss := Copy(s, Pos(',', s) + 1, Length(s));
            s := ss;
            ss := '';
            ss := Copy(s, 0, Pos(',', s) - 1);
            TreePolygonVertices[Incrementer, i, 1] := strtofloat(ss);
            ss := '';
            ss := Copy(s, Pos(',', s) + 1, Length(s));
            s := ss;
            TreePolygonVertices[Incrementer, i, 2] := strtofloat(s);
          end;
        End;
      except
        { On known exceptions show an error message. }
        on EConvertError do
          MessageDlg(OpenShapeDialog.Filename +
            ' is not a valid tree shape file!', mtError, [mbOK], 0);
        on EInOutError do
          MessageDlg('Error while writing ' + OpenShapeDialog.Filename + '!',
            mtError, [mbOK], 0);
        else
          { Show a general error message }
          MessageDlg('Unknown error while reading ' + OpenShapeDialog.Filename +
            '!', mtError, [mbOK], 0);
      end;
    finally
      CloseFile(f);
    end;
  end;
end;

procedure TaGlsTreeForm.SaveTreeShapeBtnClick(Sender: TObject);
begin { GlsShapePath }
  if TMenuItem(Sender).Name = 'ShapeSaveAs' then
  begin
    GlsShapePath := ExtractFilePath(TreeShapeEdit.Text);
    SaveShapeDialog.Initialdir := GlsShapePath;
    SaveShapeDialog.Filename := TreeShapeEdit.Text;
    if SaveShapeDialog.Execute then
    begin
      SaveTreeShape(SaveShapeDialog.Filename);
      TreeShapeEdit.Text := SaveShapeDialog.Filename;
      GlsShapePath := ExtractFilePath(TreeShapeEdit.Text);
    end;
  end
  else
  begin
    if TreeShapeEdit.Text = '' then
    begin
      SaveShapeDialog.Initialdir := GlsShapePath;
      if SaveShapeDialog.Execute then
      begin
        SaveTreeShape(SaveShapeDialog.Filename);
        TreeShapeEdit.Text := SaveShapeDialog.Filename;
        GlsShapePath := ExtractFilePath(TreeShapeEdit.Text);
      end;
    end
    else
    begin
      SaveTreeShape(TreeShapeEdit.Text);
      GlsShapePath := ExtractFilePath(TreeShapeEdit.Text);
    end;
  end;
end;

procedure TaGlsTreeForm.SaveTreeShape(Filename: String);
var
  f: TextFile;
  Incrementer, i: Integer;
begin
  try
    AssignFile(f, Filename);
    Rewrite(f);
    try
      For Incrementer := 0 to 4 do
      Begin
        Writeln(f, Inttostr(TreePolygonVerticesNumber[Incrementer]));
        For i := 0 to TreePolygonVerticesNumber[Incrementer] do
        begin
          Writeln(f, Inttostr(TreePolyImageVertices[Incrementer, i, 0]) + ',' +
            Inttostr(TreePolyImageVertices[Incrementer, i, 1]) + ',' +
            FloatToStr(TreePolygonVertices[Incrementer, i, 0]) + ',' +
            FloatToStr(TreePolygonVertices[Incrementer, i, 1]) + ',' +
            FloatToStr(TreePolygonVertices[Incrementer, i, 2]));
        end;
      End;
    except
      { On known exceptions show an error message. }
      on EConvertError do
        MessageDlg(Filename + ' is not a valid tree definition file!', mtError,
          [mbOK], 0);
      on EInOutError do
        MessageDlg('Error while writing ' + Filename + '!', mtError, [mbOK], 0);

      else
        { Show a general error message }
        MessageDlg('Unknown error while writing ' + Filename + '!', mtError,
          [mbOK], 0);
    end;
  finally
    CloseFile(f);
  end;
end;

procedure TaGlsTreeForm.LoadTreeBarkBtnClick(Sender: TObject);
begin
  OpenPictureDialog1.Initialdir := GlsTexturePath;
  if OpenPictureDialog1.Execute then
  begin
    GlsTexturePath := ExtractFilePath(OpenPictureDialog1.Filename);
    TreeBarkEdit.Text := OpenPictureDialog1.Filename;
  end;
end;

procedure TaGlsTreeForm.PickTreeColorBtnClick(Sender: TObject);
begin
  LeafColorDialog.Color := TreeColorShape.Brush.Color;
  if LeafColorDialog.Execute then
  begin
    TreeColorShape.Brush.Color := LeafColorDialog.Color;
  end;
end;
// -----------------------------------------------------
// -----------------------------------------------------

// -----------------------------------------------------
procedure TaGlsTreeForm.LeafShapeComboBoxChange(Sender: TObject);
begin { Need to Verify that files exist ELSE change back to 0 }
  if LeafShapeChecker(LeafShapeComboBox.ItemIndex) = False then
    LeafShapeComboBox.ItemIndex := 0;
end;

Function TaGlsTreeForm.LeafShapeChecker(LeafShape: Integer): Boolean;
var
  TempShapePath: String;
Begin
  TempShapePath := ExtractFilePath(ParamStr(0)) + 'tree data\';
  TempShapePath := TempShapePath + 'leaf_oval_black_gum.lsf';
  Case LeafShape of
    0:
      Begin
        if FileExists(TempShapePath) then
        begin
          LeafShapeEdit.Text := TempShapePath;
          GlsShapePath := ExtractFilePath(TempShapePath);
          LoadLeafShape(TempShapePath, 0);
          Result := True;
        end
        else
        Begin
          showmessage(TempShapePath + ' Not found' + #10#13 +
            'Do NOT do Textures');
          Result := False;
        end;
      end;
    1: { User Defined }
      Begin
        if FileExists(LeafShapeEdit.Text) then
        begin
          GlsShapePath := ExtractFilePath(LeafShapeEdit.Text);
          LoadLeafShape(LeafShapeEdit.Text, 1);
          Result := True;
        end
        else
          Result := False;
      end;
  else
    Result := False;
  End;
  if (Result = False) then
    LeafShapeEdit.Text := ''; { TempShapePath; }
end;
// -----------------------------------------------------

procedure TaGlsTreeForm.LeafImageBtnClick(Sender: TObject);
var
  s: String;
Begin
  s := TreeImageEdit.Text;
  if LoadImage(s) then
  begin
    LeafImageEdit.Text := s;
    TreeImageLoaded := False;
    LeafImageLoaded := True;
    FruitImageLoaded := False;
    ImageLoaded := True;
  end
  else
    LeafImageEdit.Text := '';
end;

procedure TaGlsTreeForm.LeafShapeBtnClick(Sender: TObject);
begin { Shape file (tsf, lsf, fsf) }
  OpenShapeDialog.Initialdir := GlsShapePath;
  if OpenShapeDialog.Execute then
  begin
    LeafShapeEdit.Text := OpenShapeDialog.Filename;
    GlsShapePath := ExtractFilePath(LeafShapeEdit.Text);
    LoadLeafShape(OpenShapeDialog.Filename, 1);
  end;
end;

procedure TaGlsTreeForm.LeafShapeSaverBtnClick(Sender: TObject);
begin { GlsShapePath }
  if TMenuItem(Sender).Name = 'ShapeSaveAs1' then
  begin
    GlsShapePath := ExtractFilePath(LeafShapeEdit.Text);
    SaveShapeDialog.Initialdir := GlsShapePath;
    SaveShapeDialog.Filename := LeafShapeEdit.Text;
    if SaveShapeDialog.Execute then
    begin
      SaveLeafShape(SaveShapeDialog.Filename);
      LeafShapeEdit.Text := SaveShapeDialog.Filename;
      GlsShapePath := ExtractFilePath(LeafShapeEdit.Text);
    end;
  end
  else
  begin
    if LeafShapeEdit.Text = '' then
    begin
      SaveShapeDialog.Initialdir := GlsShapePath;
      if SaveShapeDialog.Execute then
      begin
        SaveLeafShape(SaveShapeDialog.Filename);
        LeafShapeEdit.Text := SaveShapeDialog.Filename;
        GlsShapePath := ExtractFilePath(LeafShapeEdit.Text);
      end;
    end
    else
    begin
      SaveLeafShape(LeafShapeEdit.Text);
      GlsShapePath := ExtractFilePath(LeafShapeEdit.Text);
    end;
  end;
end;

// GlsShapePath FruitShape if loaded then use ELSE a SPhere!
procedure TaGlsTreeForm.LoadLeafShape(Filename: string; InShape: Integer);
var
  f: TextFile;
  ImageToo: Boolean;
  i: Integer;
  ss, s: string;
begin
  try
    AssignFile(f, Filename);
    Reset(f);
    try
      Readln(f, s); { showmessage('0: '+s); }
      LeafPolygonVerticesNumber[1] := StrtoInt(s);
      Readln(f, s);
      if StrtoInt(s) = 1 then
        ImageToo := True
      else
        ImageToo := False;
      SetLength(LeafPolygonVertices[InShape],
        LeafPolygonVerticesNumber[InShape] + 1, 3);
      SetLength(LeafPolyImageVertices, LeafPolygonVerticesNumber[InShape] + 1);
      For i := 0 to LeafPolygonVerticesNumber[InShape] do
      begin
        Readln(f, s); { Copy(S; Index, Count: Integer): string; }
        ss := Copy(s, 0, Pos(',', s) - 1);
        LeafPolyImageVertices[i, 0] := StrtoInt(ss); { showmessage('1: '+ss); }
        ss := Copy(s, Pos(',', s) + 1, Length(s));
        s := ss; { showmessage('2a: '+ss); }
        ss := Copy(s, 0, Pos(',', s) - 1); { showmessage('2b: '+ss); }
        LeafPolyImageVertices[i, 1] := StrtoInt(ss);
        ss := Copy(s, Pos(',', s) + 1, Length(s));
        s := ss;
        ss := Copy(s, 0, Pos(',', s) - 1); { showmessage('x: '+ss); }
        LeafPolygonVertices[InShape, i, 0] := strtofloat(ss);
        ss := Copy(s, Pos(',', s) + 1, Length(s));
        s := ss;
        ss := Copy(s, 0, Pos(',', s) - 1);
        LeafPolygonVertices[InShape, i, 1] := strtofloat(ss);
        { showmessage('y: '+ss); }
        ss := Copy(s, Pos(',', s) + 1, Length(s));
        s := ss; { showmessage('z: '+ss); }
        { ss:=Copy(s,0,Pos(',', S)); }
        LeafPolygonVertices[InShape, i, 2] := strtofloat(s);
      end;
      if (not ImageToo) then
        ComputeLeafImageCoords;
    except
      { On known exceptions show an error message. }
      on EConvertError do
        MessageDlg(Filename + ' is not a valid tree definition file!', mtError,
          [mbOK], 0);
      on EInOutError do
        MessageDlg('Error while writing ' + Filename + '!', mtError, [mbOK], 0);
      else
        { Show a general error message }
        MessageDlg('Unknown error while reading ' + Filename + '!', mtError,
          [mbOK], 0);
    end;
  finally
    CloseFile(f);
  end;
end;

procedure TaGlsTreeForm.SaveLeafShape(Filename: string);
var
  f: TextFile;
  i: Integer;
begin
  try
    AssignFile(f, Filename);
    Rewrite(f);
    try
      Writeln(f, Inttostr(LeafPolygonVerticesNumber[1]));
      Writeln(f, 1); { Image too }
      For i := 0 to LeafPolygonVerticesNumber[1] do
      begin
        Writeln(f, Inttostr(LeafPolyImageVertices[i, 0]) + ',' +
          Inttostr(LeafPolyImageVertices[i, 1]) + ',' +
          FloatToStr(LeafPolygonVertices[1, i, 0]) + ',' +
          FloatToStr(LeafPolygonVertices[1, i, 1]) + ',' +
          FloatToStr(LeafPolygonVertices[1, i, 2]));
      end;
    except
      { On known exceptions show an error message. }
      on EConvertError do
        MessageDlg(Filename + ' is not a valid tree definition file!', mtError,
          [mbOK], 0);
      on EInOutError do
        MessageDlg('Error while writing ' + Filename + '!', mtError, [mbOK], 0);

      else
        { Show a general error message }
        MessageDlg('Unknown error while writing ' + Filename + '!', mtError,
          [mbOK], 0);
    end;
  finally
    CloseFile(f);
  end;
end;

procedure TaGlsTreeForm.LeafTextureBtnClick(Sender: TObject);
begin { just loads the File name - no display }
  OpenPictureDialog1.Initialdir := GlsTexturePath;
  if OpenPictureDialog1.Execute then
  begin
    GlsTexturePath := ExtractFilePath(OpenPictureDialog1.Filename);
    LeafTextureEdit.Text := OpenPictureDialog1.Filename;
  end;
end;

procedure TaGlsTreeForm.PickLeafColorBtnClick(Sender: TObject);
begin { LeafColorDialog }
  LeafColorDialog.Color := LeafColorShape.Brush.Color;
  if LeafColorDialog.Execute then
  begin
    LeafColorShape.Brush.Color := LeafColorDialog.Color;
  end;
end;

procedure TaGlsTreeForm.PickLeafBackColorBtnClick(Sender: TObject);
begin
  LeafColorDialog.Color := LeafBackColorShape.Brush.Color;
  if LeafColorDialog.Execute then
  begin
    LeafBackColorShape.Brush.Color := LeafColorDialog.Color;
  end;
end;
// -----------------------------------------------------
// -----------------------------------------------------

procedure TaGlsTreeForm.ManOpenLeafShapeFileBtnClick(Sender: TObject);
begin { Shape file (tsf, lsf, fsf) }
  OpenShapeDialog.Initialdir := GlsShapePath;
  if OpenShapeDialog.Execute then
  begin
    ManualShapeInputFilenameEdit.Text := OpenShapeDialog.Filename;
    GlsShapePath := ExtractFilePath(OpenShapeDialog.Filename);
    LoadLeafShape(OpenShapeDialog.Filename, 1);
    RichEdit1.Lines.LoadfromFile(OpenShapeDialog.Filename);
  end;
end;

procedure TaGlsTreeForm.ManSaveLeafShapeFileBtnClick(Sender: TObject);
begin
  GlsShapePath := ExtractFilePath(ManualShapeInputFilenameEdit.Text);
  SaveShapeDialog.Initialdir := GlsShapePath;
  SaveShapeDialog.Filename := ManualShapeInputFilenameEdit.Text;
  if SaveShapeDialog.Execute then
  begin
    RichEdit1.Lines.Savetofile(SaveShapeDialog.Filename);
    ManualShapeInputFilenameEdit.Text := SaveShapeDialog.Filename;
    GlsShapePath := ExtractFilePath(ManualShapeInputFilenameEdit.Text);
  end;
end;

procedure TaGlsTreeForm.ManOpenFruitShapeFileBtnClick(Sender: TObject);
begin { Shape file (tsf, lsf, fsf) }
  OpenShapeDialog.Initialdir := GlsShapePath;
  if OpenShapeDialog.Execute then
  begin
    ManualShapeInputFilenameEdit.Text := OpenShapeDialog.Filename;
    GlsShapePath := ExtractFilePath(OpenShapeDialog.Filename);
    LoadFruitShape(OpenShapeDialog.Filename);
    RichEdit1.Lines.LoadfromFile(OpenShapeDialog.Filename);
  end;
end;

procedure TaGlsTreeForm.ManSaveFruitShapeFileBtnClick(Sender: TObject);
begin
  GlsShapePath := ExtractFilePath(ManualShapeInputFilenameEdit.Text);
  SaveShapeDialog.Initialdir := GlsShapePath;
  SaveShapeDialog.Filename := ManualShapeInputFilenameEdit.Text;
  if SaveShapeDialog.Execute then
  begin
    RichEdit1.Lines.Savetofile(SaveShapeDialog.Filename);
    ManualShapeInputFilenameEdit.Text := SaveShapeDialog.Filename;
    GlsShapePath := ExtractFilePath(ManualShapeInputFilenameEdit.Text);
  end;
end;

procedure TaGlsTreeForm.ManDisplayLeafBtnClick(Sender: TObject);
begin
  { ManualShapeInputFilenameEdit
    RichEdit1
    TracerImage  Sized to fit X -0.5..0.5  Y 0..1 }
  ManSaveLeafShapeFileBtnClick(Self);
  LoadLeafShape(SaveShapeDialog.Filename, 1);
  ComputeLeafImageCoords;
  BlankCanvas;
  DrawTracedShape(2);
end;

procedure TaGlsTreeForm.ManDisplayFruitBtnClick(Sender: TObject);
begin
  ManSaveFruitShapeFileBtnClick(Self);
  LoadFruitShape(SaveShapeDialog.Filename);
  { moved INTO Loader  ComputeFruitImageCoords; }
  { BlankCanvas; }
  DrawTracedShape(1);
  { Replace the Non image with an Image Coordinate version }
  SaveFruitShape(SaveShapeDialog.Filename);
end;

procedure TaGlsTreeForm.BlankCanvas;
begin
  TreeImageLoaded := False; { Set these false so ONLY 1 can be edited }
  LeafImageLoaded := False;
  FruitImageLoaded := False;
  ImageLoaded := False;
  TICNoneClick(Self);
  GrabberImageBitmap.Width := 256;
  GrabberImageBitmap.Height := 256;
  GrabberImageBitmap.Canvas.Brush.Color := clWhite;
  GrabberImageBitmap.Canvas.FillRect(Rect(0, 0, 256, 256));
  TracerImage.Width := GrabberImageBitmap.Width;
  TracerImage.Height := GrabberImageBitmap.Height;
  TracerImage.Picture.Assign(GrabberImageBitmap);
end;

// -----------------------------------------------------
// -----------------------------------------------------
procedure TaGlsTreeForm.PickFruitColorBtnClick(Sender: TObject);
begin
  LeafColorDialog.Color := FruitColorShape.Brush.Color;
  if LeafColorDialog.Execute then
  begin
    FruitColorShape.Brush.Color := LeafColorDialog.Color;
  end;
end;

procedure TaGlsTreeForm.FruitTextureBtnClick(Sender: TObject);
begin { just loads the File name - no display }
  OpenPictureDialog1.Initialdir := GlsTexturePath;
  if OpenPictureDialog1.Execute then
  begin
    GlsTexturePath := ExtractFilePath(OpenPictureDialog1.Filename);
    FruitTextureEdit.Text := OpenPictureDialog1.Filename;
  end;
end;

procedure TaGlsTreeForm.FruitImageBtnClick(Sender: TObject);
var
  s: String;
Begin
  s := FruitImageEdit.Text;
  if LoadImage(s) then
  begin
    FruitImageEdit.Text := s;
    TreeImageLoaded := False;
    LeafImageLoaded := False;
    FruitImageLoaded := True;
    ImageLoaded := True;
  end
  else
    FruitImageEdit.Text := '';
end;

procedure TaGlsTreeForm.FruitShapeFileBtnClick(Sender: TObject);
begin
  { Shape file (tsf, lsf, fsf) }
  OpenShapeDialog.Initialdir := GlsShapePath;
  if OpenShapeDialog.Execute then
  begin
    FruitShapeFileEdit.Text := OpenShapeDialog.Filename;
    GlsShapePath := ExtractFilePath(FruitShapeFileEdit.Text);
    LoadFruitShape(OpenShapeDialog.Filename);
  end;
end;

procedure TaGlsTreeForm.FruitShapeSaverBtnClick(Sender: TObject);
begin { GlsShapePath }
  if TMenuItem(Sender).Name = 'ShapeSaveAs2' then
  begin
    GlsShapePath := ExtractFilePath(FruitShapeFileEdit.Text);
    SaveShapeDialog.Initialdir := GlsShapePath;
    SaveShapeDialog.Filename := FruitShapeFileEdit.Text;
    if SaveShapeDialog.Execute then
    begin
      SaveFruitShape(SaveShapeDialog.Filename);
      FruitShapeFileEdit.Text := SaveShapeDialog.Filename;
      GlsShapePath := ExtractFilePath(FruitShapeFileEdit.Text);
    end;
  end
  else
  begin
    if FruitShapeFileEdit.Text = '' then
    begin
      SaveShapeDialog.Initialdir := GlsShapePath;
      if SaveShapeDialog.Execute then
      begin
        SaveFruitShape(SaveShapeDialog.Filename);
        FruitShapeFileEdit.Text := SaveShapeDialog.Filename;
        GlsShapePath := ExtractFilePath(FruitShapeFileEdit.Text);
      end;
    end
    else
    begin
      SaveFruitShape(FruitShapeFileEdit.Text);
      GlsShapePath := ExtractFilePath(FruitShapeFileEdit.Text);
    end;
  end;
end;

{ GlsShapePath FruitShape if loaded then use ELSE a SPhere! }
procedure TaGlsTreeForm.LoadFruitShape(Filename: string);
var
  f: TextFile;
  ImageToo: Boolean;
  X, Y, i: Integer;
  ss, s: string;
begin
  try
    AssignFile(f, Filename);
    Reset(f);
    try
      Readln(f, s);
      FruitPolygonVerticesNumber := StrtoInt(s);
      Readln(f, s);
      if StrtoInt(s) = 1 then
        ImageToo := True
      else
        ImageToo := False;
      Readln(f, s);
      X := StrtoInt(s);
      Readln(f, s);
      Y := StrtoInt(s);
      SetLength(FruitPolyImageVertices, FruitPolygonVerticesNumber + 1);
      SetLength(FruitPolygonVertices, FruitPolygonVerticesNumber + 1);
      For i := 0 to FruitPolygonVerticesNumber do
      begin { FruitPolyImageVertices }
        Readln(f, s);
        ss := Copy(s, 0, Pos(',', s) - 1);
        FruitPolyImageVertices[i, 0] := StrtoInt(ss);
        ss := Copy(s, Pos(',', s) + 1, Length(s));
        s := ss;
        ss := Copy(s, 0, Pos(',', s) - 1);
        FruitPolyImageVertices[i, 1] := StrtoInt(ss);
        ss := Copy(s, Pos(',', s) + 1, Length(s));
        s := ss;
        ss := Copy(s, 0, Pos(',', s) - 1);
        FruitPolygonVertices[i, 0] := strtofloat(ss);
        ss := Copy(s, Pos(',', s) + 1, Length(s));
        s := ss;
        ss := Copy(s, 0, Pos(',', s) - 1);
        FruitPolygonVertices[i, 1] := strtofloat(ss);
        ss := Copy(s, Pos(',', s) + 1, Length(s));
        s := ss;
        { ss:=Copy(s,0,Pos(',', S)); }
        FruitPolygonVertices[i, 2] := strtofloat(s);
      end;
      if (not ImageToo) then
        ComputeFruitImageCoords(X, Y);

    except
      { On known exceptions show an error message. }
      on EConvertError do
        MessageDlg(Filename + ' is not a valid tree definition file!', mtError,
          [mbOK], 0);
      on EInOutError do
        MessageDlg('Error while writing ' + Filename + '!', mtError, [mbOK], 0);
      else
        { Show a general error message }
        MessageDlg('Unknown error while reading ' + Filename + '!', mtError,
          [mbOK], 0);
    end;
  finally
    CloseFile(f);
  end;
end;

procedure TaGlsTreeForm.SaveFruitShape(Filename: string);
var
  f: TextFile;
  i: Integer;
begin
  try
    AssignFile(f, Filename);
    Rewrite(f);
    try
      Writeln(f, Inttostr(FruitPolygonVerticesNumber));
      Writeln(f, 1); { Image too }
      Writeln(f, Inttostr(TracerImage.Width));
      Writeln(f, Inttostr(TracerImage.Height));
      For i := 0 to FruitPolygonVerticesNumber do
      begin
        Writeln(f, Inttostr(FruitPolyImageVertices[i, 0]) + ',' +
          Inttostr(FruitPolyImageVertices[i, 1]) + ',' +
          FloatToStr(FruitPolygonVertices[i, 0]) + ',' +
          FloatToStr(FruitPolygonVertices[i, 1]) + ',' +
          FloatToStr(FruitPolygonVertices[i, 2]));
      end;
    except
      { On known exceptions show an error message. }
      on EConvertError do
        MessageDlg(Filename + ' is not a valid tree definition file!', mtError,
          [mbOK], 0);
      on EInOutError do
        MessageDlg('Error while writing ' + Filename + '!', mtError, [mbOK], 0);

      else
        { Show a general error message }
        MessageDlg('Unknown error while writing ' + Filename + '!', mtError,
          [mbOK], 0);
    end;
  finally
    CloseFile(f);
  end;
end;
// -----------------------------------------------------
// -----------------------------------------------------

// -----------------------------------------------------
// -----------------------------------------------------
procedure TaGlsTreeForm.BaseExtentsClick(Sender: TObject);
begin
  TreeShapeRG.ItemIndex := 0;
end;

procedure TaGlsTreeForm.FirstLimbLevelClick(Sender: TObject);
begin
  TreeShapeRG.ItemIndex := 1;
end;

procedure TaGlsTreeForm.SecondLimbLevelClick(Sender: TObject);
begin
  TreeShapeRG.ItemIndex := 2;
end;

procedure TaGlsTreeForm.ThirdLimbLevelClick(Sender: TObject);
begin
  TreeShapeRG.ItemIndex := 3;
end;

procedure TaGlsTreeForm.FourthLimbLevelClick(Sender: TObject);
begin
  TreeShapeRG.ItemIndex := 4;
end;

procedure TaGlsTreeForm.FifthLimbLevelClick(Sender: TObject);
begin
  TreeShapeRG.ItemIndex := 5;
end;

procedure TaGlsTreeForm.TreeShapeRGClick(Sender: TObject);
begin
  FruityLeafStarted := False;
  Case TreeShapeRG.ItemIndex of
    0:
      BaseExtents.Checked := True;
    1:
      FirstLimbLevel.Checked := True;
    2:
      SecondLimbLevel.Checked := True;
    3:
      FourthLimbLevel.Checked := True;
    4:
      FifthLimbLevel.Checked := True;
  end;
end;
// -----------------------------------------------------
// -----------------------------------------------------

procedure TaGlsTreeForm.TICNoneClick(Sender: TObject);
begin
  TICRG.ItemIndex := 0;
end;

procedure TaGlsTreeForm.TraceInput1Click(Sender: TObject);
begin
  TICRG.ItemIndex := 1;
end;

procedure TaGlsTreeForm.FTracerFinished1Click(Sender: TObject);
begin
  TICRG.ItemIndex := 2;
end;

procedure TaGlsTreeForm.CClear1Click(Sender: TObject);
begin
  TICRG.ItemIndex := 3;
end;

procedure TaGlsTreeForm.DDraw1Click(Sender: TObject);
begin
  TICRG.ItemIndex := 4;
end;

procedure TaGlsTreeForm.ADrawAll1Click(Sender: TObject);
begin
  TICRG.ItemIndex := 5;
end;

procedure TaGlsTreeForm.TICRGClick(Sender: TObject);
var
  i: Integer;
begin
  Case TICRG.ItemIndex of
    0:
      begin
        Drawing := False;
        Screen.Cursor := crDefault;
        TICNone.Checked := True;
        StatusBar.Panels[1].Text := 'Active Tracer: None';
      end;
    1:
      if (ImageLoaded) then
      begin
        TICRG.ItemIndex := 3;
        TICRGClick(Sender); { CLEAR whatever else ADDS points }
        Application.ProcessMessages;
        Drawing := True;
        Screen.Cursor := crCross;
        TraceInput1.Checked := True;
        if TreeImageLoaded then
          StatusBar.Panels[1].Text := 'Active Tracer: Tree'
        else if LeafImageLoaded then
          StatusBar.Panels[1].Text := 'Active Tracer: Leaf'
        else if FruitImageLoaded then
          StatusBar.Panels[1].Text := 'Active Tracer: Fruit'
      end
      else
        TICRG.ItemIndex := 0;
    2:
      if (ImageLoaded) then
      begin
        Drawing := False;
        Screen.Cursor := crDefault;
        { Finish: Compute the DATA into ARRAY Coordinates }
        if TreeImageLoaded then
          ComputeTreeRealCoords
        else if LeafImageLoaded then
          ComputeLeafRealCoords
        else if FruitImageLoaded then
          ComputeFruitRealCoords;
        { Finished SO Reset to doing Nothing }
        TICNone.Checked := True;
        StatusBar.Panels[1].Text := 'Active Tracer: None';
      end
      else
        TICRG.ItemIndex := 0;
    3:
      if (ImageLoaded) then
      begin
        Drawing := False;
        Screen.Cursor := crDefault;
        CClear1.Checked := True;
        TracerImage.Picture.Assign(GrabberImageBitmap);
        if FruitImageLoaded then
        begin
          FruitPolygonVerticesNumber := -1;
          SetLength(FruitPolyImageVertices, 0);
          SetLength(FruitPolygonVertices, 0);
        end;
        if LeafImageLoaded then
        begin
          LeafPolygonVerticesNumber[1] := -1;
          SetLength(LeafPolygonVertices[1], 0);
          SetLength(LeafPolyImageVertices, 0);
        end;
        if TreeImageLoaded then
        begin
          for i := 0 to 5 do
            TreePolygonVerticesNumber[i] := -1;
          SetLength(TreePolyImageVertices, 0);
          SetLength(TreePolyImageVertices, 6);
          SetLength(TreePolygonVertices, 0);
          SetLength(TreePolygonVertices, 6);
        end;
      end
      else
        TICRG.ItemIndex := 0;
    4:
      if (ImageLoaded) then
      begin
        Drawing := False;
        Screen.Cursor := crDefault;
        DDraw1.Checked := True;
        TracerImage.Picture.Assign(GrabberImageBitmap);
        if FruitImageLoaded then
          DrawTracedShape(1);
        if LeafImageLoaded then
          DrawTracedShape(2);
        if TreeImageLoaded then
          DrawTracedShape(3);
      end
      else
        TICRG.ItemIndex := 0;
    5:
      if (ImageLoaded and TreeImageLoaded) then
      begin
        Drawing := False;
        Screen.Cursor := crDefault;
        ADrawAll1.Checked := True;
        TracerImage.Picture.Assign(GrabberImageBitmap);
        DrawTracedShape(4);
      end
      else
        TICRG.ItemIndex := 0;
  end;
end;

// -----------------------------------------------------
{ TreeImageLoaded  DrawTracedShape; } { LeafImageLoaded }
{ FruitImageLoaded }
// -----------------------------------------------------
procedure TaGlsTreeForm.TracerImageMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if (Drawing and ImageLoaded) then
  begin
    TracerImage.Canvas.Pen.Width := 2;
    TracerImage.Canvas.Pen.Color := clAqua;
    if (TreeImageLoaded) then
      Case TreeShapeRG.ItemIndex of
        0:
          TracerImage.Canvas.Pen.Color := clBlack;
        1:
          TracerImage.Canvas.Pen.Color := clAqua;
        2:
          TracerImage.Canvas.Pen.Color := clRed;
        3:
          TracerImage.Canvas.Pen.Color := clFuchsia;
        4:
          TracerImage.Canvas.Pen.Color := clYellow;
        5:
          TracerImage.Canvas.Pen.Color := clSilver;
      end;
    TracerImage.Canvas.MoveTo(X, Y);
    if (not FruityLeafStarted) then
    begin
      Origin := Point(X, Y);
      FruityLeafStarted := True;
    end;
    MovePt := Point(X, Y);
    DrawingTool := dtLine;
    Screen.Cursor := crCross;
  end;
end;

procedure TaGlsTreeForm.TracerImageMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
var
  Xs, Ys: String;
begin
  if (Drawing and ImageLoaded) then
  begin
    DrawShape(Origin, MovePt, DIYX3Y3, DIYX4Y4, pmNotXor);
    MovePt := Point(X, Y);
    DrawShape(Origin, MovePt, DIYX3Y3, DIYX4Y4, pmNotXor);
  end;
  str(X, Xs);
  str(Y, Ys);
  StatusBar.Panels[0].Text := '   X: ' + Xs + ', Y: ' + Ys;
end;

procedure TaGlsTreeForm.TracerImageMouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if (Drawing and ImageLoaded) then
  begin
    { DrawingTool := dtRectangle; }
    { Drawing := False; }
    { DrawShape(Origin, MovePt, DIYX3Y3, DIYX4Y4, pmCopy); }
    TracerImage.Canvas.Rectangle(X + 2, Y + 2, X - 2, Y - 2);

    { Screen.Cursor := crDefault; }
    if FruitImageLoaded then
    begin
      inc(FruitPolygonVerticesNumber);
      StatusBar.Panels[1].Text := Inttostr(FruitPolygonVerticesNumber);
      SetLength(FruitPolyImageVertices, FruitPolygonVerticesNumber + 1);
      SetLength(FruitPolygonVertices, FruitPolygonVerticesNumber + 1);
      FruitPolyImageVertices[FruitPolygonVerticesNumber, 0] := X;
      FruitPolyImageVertices[FruitPolygonVerticesNumber, 1] := Y;
      FruitPolygonVertices[FruitPolygonVerticesNumber, 0] := X;
      FruitPolygonVertices[FruitPolygonVerticesNumber, 1] := Y;
      FruitPolygonVertices[FruitPolygonVerticesNumber, 2] := 0;
    end;
    if (LeafImageLoaded) then
    begin
      inc(LeafPolygonVerticesNumber[1]);
      StatusBar.Panels[1].Text := Inttostr(LeafPolygonVerticesNumber[1]);
      SetLength(LeafPolyImageVertices, LeafPolygonVerticesNumber[1] + 1);
      SetLength(LeafPolygonVertices[1], LeafPolygonVerticesNumber[1] + 1, 3);
      LeafPolyImageVertices[LeafPolygonVerticesNumber[1], 0] := X;
      LeafPolyImageVertices[LeafPolygonVerticesNumber[1], 1] := Y;
      LeafPolygonVertices[1, LeafPolygonVerticesNumber[1], 0] := X;
      LeafPolygonVertices[1, LeafPolygonVerticesNumber[1], 1] := Y;
      LeafPolygonVertices[1, LeafPolygonVerticesNumber[1], 2] := 0;
    end;
    if TreeImageLoaded then
    begin
      inc(TreePolygonVerticesNumber[TreeShapeRG.ItemIndex]);
      StatusBar.Panels[1].Text :=
        Inttostr(TreePolygonVerticesNumber[TreeShapeRG.ItemIndex]);
      SetLength(TreePolyImageVertices[TreeShapeRG.ItemIndex],
        (TreePolygonVerticesNumber[TreeShapeRG.ItemIndex] + 1), 2);
      SetLength(TreePolygonVertices[TreeShapeRG.ItemIndex],
        TreePolygonVerticesNumber[TreeShapeRG.ItemIndex] + 1, 3);
      TreePolyImageVertices[TreeShapeRG.ItemIndex,
        TreePolygonVerticesNumber[TreeShapeRG.ItemIndex], 0] := X;
      TreePolyImageVertices[TreeShapeRG.ItemIndex,
        TreePolygonVerticesNumber[TreeShapeRG.ItemIndex], 1] := Y;
      TreePolygonVertices[TreeShapeRG.ItemIndex,
        TreePolygonVerticesNumber[TreeShapeRG.ItemIndex], 0] := X;
      TreePolygonVertices[TreeShapeRG.ItemIndex,
        TreePolygonVerticesNumber[TreeShapeRG.ItemIndex], 1] := Y;
      TreePolygonVertices[TreeShapeRG.ItemIndex,
        TreePolygonVerticesNumber[TreeShapeRG.ItemIndex], 2] := 0;
    end;
  end;
end;

// -----------------------------------------------------
procedure TaGlsTreeForm.DrawShape(TopLeft, BottomRight, Tri, Quad: TPoint;
  AMode: TPenMode);
var
  TheRect: TRect;
begin
  with TracerImage.Canvas do
  begin
    Pen.Mode := AMode;
    case DrawingTool of
      dtLine:
        begin
          TracerImage.Canvas.MoveTo(TopLeft.X, TopLeft.Y);
          TracerImage.Canvas.LineTo(BottomRight.X, BottomRight.Y);
        end; { DrawingTool := dtVRectangle; }
      dtVDRectangle, dtVTRectangle, dtVFRectangle, dtVNRectangle, dtVMRectangle,
        dtVARectangle, dtVWRectangle, dtVCRectangle, dtVSRectangle,
        dtVBRectangle, dtVRectangle:
        begin
          TheRect.TopLeft := TopLeft;
          TheRect.BottomRight := BottomRight;
          { (TopLeft.X, TopLeft.Y, BottomRight.X, BottomRight.Y); }
          TracerImage.Canvas.FrameRect(TheRect);
        end;
      dtRectangle: { using MovePt only }
        TracerImage.Canvas.Rectangle(BottomRight.X + 2, BottomRight.Y + 2,
          BottomRight.X - 2, BottomRight.Y - 2);
      dtCSEllipse, dtEllipse:
        TracerImage.Canvas.Ellipse(TopLeft.X, TopLeft.Y, BottomRight.X,
          BottomRight.Y);
      dtPBrush:
        TracerImage.Canvas.Ellipse(TopLeft.X, TopLeft.Y,
          (TopLeft.X + DrawingToolPBrushWidth),
          (TopLeft.Y + DrawingToolPBrushWidth));
      dtRoundRect:
        TracerImage.Canvas.RoundRect(TopLeft.X, TopLeft.Y, BottomRight.X,
          BottomRight.Y, (TopLeft.X - BottomRight.X) div 2,
          (TopLeft.Y - BottomRight.Y) div 2);
    end;
    Pen.Mode := pmCopy;
  end;
end;

// -----------------------------------------------------
// -----------------------------------------------------
{ TreeImageLoaded  DrawTracedShape; } { LeafImageLoaded }
{ FruitImageLoaded }
procedure TaGlsTreeForm.DrawTracedShape(Which: Integer);
var
  RecursiveI, Xi, Yi, i: Integer;
Begin
  { Refresh }
  { TracerImage.Width := GrabberImageBitmap.Width;
    TracerImage.Height := GrabberImageBitmap.Height;
    TracerImage.Picture.Assign(GrabberImageBitmap); }
  TracerImage.Canvas.Pen.Color := clAqua;
  Case Which of
    1: { (FruitImageLoaded ) }
      Begin
        DrawingTool := dtRectangle;
        Drawing := False;
        For i := 0 to FruitPolygonVerticesNumber do
        begin
          Xi := FruitPolyImageVertices[i, 0];
          Yi := FruitPolyImageVertices[i, 1];
          { MovePt := Point(Xi, Yi); }
          TracerImage.Canvas.Rectangle(Xi + 2, Yi + 2, Xi - 2, Yi - 2);
          { DrawShape(Origin, MovePt, DIYX3Y3, DIYX4Y4, pmCopy); }
        end;
      end;
    2: { (LeafImageLoaded ) }
      Begin
        DrawingTool := dtRectangle;
        Drawing := False;
        For i := 0 to LeafPolygonVerticesNumber[1] do
        begin
          Xi := LeafPolyImageVertices[i, 0];
          Yi := LeafPolyImageVertices[i, 1];
          TracerImage.Canvas.Rectangle(Xi + 2, Yi + 2, Xi - 2, Yi - 2);
          { MovePt := Point(Xi, Yi);
            DrawShape(Origin, MovePt, DIYX3Y3, DIYX4Y4, pmCopy); }
        end;
      end;
    3: { (TreeImageLoaded ) }
      Begin
        Case TreeShapeRG.ItemIndex of
          0:
            TracerImage.Canvas.Pen.Color := clBlack;
          1:
            TracerImage.Canvas.Pen.Color := clAqua;
          2:
            TracerImage.Canvas.Pen.Color := clRed;
          3:
            TracerImage.Canvas.Pen.Color := clFuchsia;
          4:
            TracerImage.Canvas.Pen.Color := clYellow;
          5:
            TracerImage.Canvas.Pen.Color := clSilver;
        end;
        DrawingTool := dtRectangle;
        Drawing := False;
        For i := 0 to TreePolygonVerticesNumber[TreeShapeRG.ItemIndex] do
        begin
          Xi := TreePolyImageVertices[TreeShapeRG.ItemIndex, i, 0];
          Yi := TreePolyImageVertices[TreeShapeRG.ItemIndex, i, 1];
          TracerImage.Canvas.Rectangle(Xi + 2, Yi + 2, Xi - 2, Yi - 2);
          { MovePt := Point(Xi, Yi);
            DrawShape(Origin, MovePt, DIYX3Y3, DIYX4Y4, pmCopy); }
        end;
      end;
    4: { TreeImageLoaded  ALL }
      Begin
        For RecursiveI := 0 to 4 do
        begin
          TreeShapeRG.ItemIndex := RecursiveI;
          DrawTracedShape(3);
        end;
      end;
  end; { Case }
end;
// -----------------------------------------------------
// -----------------------------------------------------
{ Finish: Compute the DATA into IMAGE ARRAY Coordinates
  procedure TaGlsTreeForm.ComputeTreeImageCoords; }

{ Finish: Compute the DATA into REAL ARRAY Coordinates
  Actually this is to Compute Parameters...
  THERE is NO NEED for REAL coords?...
  as you cannot input manually and compute Image Coords }
procedure TaGlsTreeForm.ComputeTreeRealCoords;
var
  LevelCount, TreePart, i, MinX, MaxX, MinY, MaxY, XWidth, YHeight: Integer;
  NadaString: String;
Begin
  NadaString := '0';
  { Given x,y image coords Compute the REAL coords }
  MinX := 123456;
  MaxX := -123456;
  MinY := 123456;
  MaxY := -123456;
  LevelCount := 0;
  For TreePart := 0 to 5 do
  begin
    if TreePolygonVerticesNumber[TreePart] > 0 then
    begin
      LevelCount := TreePart;
      For i := 0 to TreePolygonVerticesNumber[TreePart] do
      begin
        if MinX > TreePolyImageVertices[TreePart, i, 0] then
          MinX := TreePolyImageVertices[TreePart, i, 0];
        if MaxX < TreePolyImageVertices[TreePart, i, 0] then
          MaxX := TreePolyImageVertices[TreePart, i, 0];
        if MinY > TreePolyImageVertices[TreePart, i, 1] then
          MinY := TreePolyImageVertices[TreePart, i, 1];
        if MaxY < TreePolyImageVertices[TreePart, i, 1] then
          MaxY := TreePolyImageVertices[TreePart, i, 1];
      end;
    end;
  end;
  XWidth := MaxX - MinX;
  YHeight := MaxY - MinY;
  For TreePart := 0 to 5 do
    For i := 0 to TreePolygonVerticesNumber[TreePart] do
    begin
      TreePolygonVertices[TreePart, i, 0] :=
        ((TreePolyImageVertices[TreePart, i, 0] - MinX) / (XWidth / 10));
      TreePolygonVertices[TreePart, i, 1] :=
        ((TreePolyImageVertices[TreePart, i, 1] - MinY) / (YHeight / 10));
    end;
  { NOW do the HARD part... Compute the Tree Parameters
    ShapeLabel }
  LevelsNumberEdit.Text := Inttostr(LevelCount);
  { BASE GENERAL }
  { ScaleFloatEdit.Text:=inttostr(Round(StrtoFloat(TreeHeightEdit.Text))); }
  ScaleVFloatEdit.Text := NadaString;
  ZScaleFloatEdit.Text := NadaString; { What is it? }
  ZScaleVFloatEdit.Text := NadaString;
  BaseSizeFloatEdit.Text := Inttostr(TreePolyImageVertices[0, 4, 1] -
    TreePolyImageVertices[0, 0, 1]);

  RatioFloatEdit.Text := NadaString;
  RatioPowerFloatEdit.Text := NadaString;
  LobesNumberEdit.Text := NadaString;
  LobeDepthFloatEdit.Text := NadaString;
  FlareFloatEdit.Text := Inttostr(TreePolyImageVertices[0, 4, 1] -
    TreePolyImageVertices[0, 0, 1]);

  { BASE TRUNK }
  { Scale0FloatEdit
    ScaleV0FloatEdit
    Length0FloatEdit.Text:=
    Inttostr(TreePolyImageVertices[0,4,1]-TreePolyImageVertices[0,0,1]);
    LengthV0FloatEdit
    Taper0FloatEdit
    Vertices0NumberEdit
    BaseSplits0NumberEdit
    SegSplits0FloatEdit
    SplitAngle0FloatEdit
    SplitAngleV0FloatEdit
    CurveRes0NumberEdit
    CurveBack0FloatEdit
    Curve0FloatEdit
    CurveV0FloatEdit }

  { FOR EACH LEVEL }
  { Length1FloatEdit
    LengthV1FloatEdit
    Taper1FloatEdit
    SplitAngle1FloatEdit
    SplitAngleV1FloatEdit
    SegSplits1FloatEdit
    Vertices1NumberEdit
    Branches1NumberEdit
    DownAngle1FloatEdit
    DownAngleV1FloatEdit
    Rotate1FloatEdit
    RotateV1FloatEdit
    CurveRes1NumberEdit
    CurveBack1FloatEdit
    Curve1FloatEdit
    CurveV1FloatEdit }
end;

{ An image should be Power of 2 : 256x256 and Square
  THUS use for the actual Texture
  The Leaf Coordinates are Also the Texture Coords :
  SO THe Moused Coords need to be converted to
  X: -0.5..0.5: 0..1  Y: 0..1
  FROM the image X,Y 0.255, 0..255 Coordinaters }
procedure TaGlsTreeForm.ComputeLeafImageCoords;
var
  i: Integer;
Begin
  For i := 0 to LeafPolygonVerticesNumber[1] do
  begin
    LeafPolyImageVertices[i, 0] :=
      Round((LeafPolygonVertices[1, i, 0] + 0.5) * 255);
    LeafPolyImageVertices[i, 1] :=
      Round((LeafPolygonVertices[1, i, 1] * 255 * -1) + 255);
  end;
end;

procedure TaGlsTreeForm.ComputeFruitImageCoords(InX, InY: Integer);
var
  i: Integer;
Begin
  For i := 0 to FruitPolygonVerticesNumber do
  begin
    FruitPolyImageVertices[i, 0] :=
      Round((FruitPolygonVertices[i, 0] + 0.5) * (InX - 1));
    FruitPolyImageVertices[i, 1] :=
      Round((FruitPolygonVertices[i, 1] * (InY - 1) * -1) + (InY - 1));
  end;
  TreeImageLoaded := False; { Set these false so ONLY 1 can be edited }
  LeafImageLoaded := False;
  FruitImageLoaded := False;
  ImageLoaded := False;
  TICNoneClick(Self);
  GrabberImageBitmap.Width := InX;
  GrabberImageBitmap.Height := InY;
  GrabberImageBitmap.Canvas.Brush.Color := clWhite;
  GrabberImageBitmap.Canvas.FillRect(Rect(0, 0, InX, InY));
  TracerImage.Width := GrabberImageBitmap.Width;
  TracerImage.Height := GrabberImageBitmap.Height;
  TracerImage.Picture.Assign(GrabberImageBitmap);
  { Save the file AS one having Image Coords }
end;

{ Given x,y image coords Compute the REAL coords.. Image ALWAYS 256x256 }
procedure TaGlsTreeForm.ComputeLeafRealCoords;
var
  i: Integer;
Begin
  For i := 0 to LeafPolygonVerticesNumber[1] do
  begin
    LeafPolygonVertices[1, i, 0] := (LeafPolyImageVertices[i, 0] / 255) - 0.5;
    LeafPolygonVertices[1, i, 1] := ((255 - LeafPolyImageVertices[i, 1]) / 255);
  end;
end;

procedure TaGlsTreeForm.ComputeFruitRealCoords;
var
  i: Integer;
Begin
  { Given x,y image coords Compute the REAL coords
    Fruit can by any size SO must USE the Image Size }
  For i := 0 to FruitPolygonVerticesNumber do
  begin
    FruitPolygonVertices[i, 0] :=
      (FruitPolyImageVertices[i, 0] / (TracerImage.Width - 1)) - 0.5;
    FruitPolygonVertices[i, 1] :=
      (((TracerImage.Height - 1) - FruitPolyImageVertices[i, 1]) /
      (TracerImage.Height - 1));
  end;
end;

// -----------------------------------------------------
// -----------------------------------------------------
procedure TaGlsTreeForm.RandomTreeSeedNumberEditChange(Sender: TObject);
begin
  RandomTreeSeedNumber := StrtoInt(RandomTreeSeedNumberEdit.Text);
end;

procedure TaGlsTreeForm.HealthTrackBarChange(Sender: TObject);
begin
  HealthLabel.Caption := Inttostr(HealthTrackBar.Position);
end;

procedure TaGlsTreeForm.DistanceTrackBarChange(Sender: TObject);
begin
  DistanceLabel.Caption := Inttostr(DistanceTrackBar.Position);
end;

procedure TaGlsTreeForm.WindStrengthTBChange(Sender: TObject);
begin
  WindStrengthLabel.Caption := Inttostr(WindStrengthTB.Position);
end;

procedure TaGlsTreeForm.WindGustTBChange(Sender: TObject);
begin
  WindGustLabel.Caption := Inttostr(WindGustTB.Position);
end;

procedure TaGlsTreeForm.WindFromTBChange(Sender: TObject);
begin
  WindFromLabel.Caption := Inttostr(WindFromTB.Position);
end;

procedure TaGlsTreeForm.SunHeightTBChange(Sender: TObject);
begin
  SunHeightLabel.Caption := Inttostr(SunHeightTB.Position);
end;

procedure TaGlsTreeForm.SunStrengthTBChange(Sender: TObject);
begin
  SunStrengthLabel.Caption := Inttostr(SunStrengthTB.Position);
end;

procedure TaGlsTreeForm.SunFromTBChange(Sender: TObject);
begin
  SunFromLabel.Caption := Inttostr(SunFromTB.Position);
end;
// -----------------------------------------------------
// -----------------------------------------------------

// -----------------------------------------------------
// -----------------------------------------------------
procedure TaGlsTreeForm.PruneShapeDisplayBtnClick(Sender: TObject);
begin // wide : 220, high : 320
  // Clear to white, Per pixel if fits then black
  // Could use Bezier? or Algo-math... dunno how
  // this is similar to what the code wants to do...
  { Draw a semi circle at base and a thinny circle at top }
  { Canvas.Pen.Color := clWhite;
    Canvas.Polyline([Point(40, 10), Point(20, 60), Point(70, 30),
    Point(10, 30), Point(60, 60), Point(40, 10)]);
    Canvas.Pen.Color := Random(65535);
    Canvas.Pen.Width := Random(7);
  }
  { PruneRatioFloatEdit
    PruneWidthFloatEdit
    PruneWidthPeakFloatEdit
    PrunePowerLowFloatEdit
    PrunePowerHighFloatEdit

    ScaleFloatEdit
    ScaleVFloatEdit
    BaseSizeFloatEdit

    Length0FloatEdit
    LengthV0FloatEdit }
  (*
    r := sqrt ( x2 + y2 + z2 )
    ratio := ( scaletree - z ) / ( scaletree *(1-BaseSize ) )
    inside := [ r / scaletree < PruneWidth *
    ShapeRatio( 8 {(envelope)}, ratio ) ]
    where ShapeRatio( 8, ratio ) is defined as
    [ ratio / ( 1 - PruneWidthPeak ) ]PrunePowerHigh
    when ratio < 1 - PruneWidthPeak, or
    [ ( 1 - ratio ) / ( 1 - PruneWidthPeak ) ]PrunePowerLow
  *)
end;
// -----------------------------------------------------

// -----------------------------------------------------
// -----------------------------------------------------

end.
